Междоменные многогранные решения

JavaScript
Междоменные многогранные решения

Доля интересных заголовков CPC коммерциализация технологии Департамент технологий - были (Zhou Zhixiang Bi Perak Hand) Приглашаем поделиться своим резюме, чтобы присоединиться к интересным заголовкам, адрес электронной почты - qianjiongli@qutousiao.net с нетерпением ждем вашего участия!.

Вы понимаете кроссдомены?

понять (продолжить) не понять (конец)

Почему возникают кроссдомены?

Междоменная проблема вызвана ограничением политики одного и того же происхождения браузера.

Почему браузеры устанавливают политику одного и того же происхождения?

Именно потому, что браузер из соображений безопасности. Без политики одинакового происхождения браузеры уязвимы дляXSSа такжеCSRFДождитесь атаки. (XSSа такжеCSRFЭто может стать дополнительной точкой знаний) В настоящее время работа веб-страницы под одним доменным именем может напрямую получать любую информацию о другой веб-странице под тем же доменным именем, или веб-страница может запрашивать данные интерфейса под разными серверами доменных имен по своему желанию. .

Что такое политика единого происхождения?

Политика того же происхождения — это соглашение, которое является одной из основных функций безопасности браузера. Так называемая политика того же происхождения относится к [протокол + доменное имя + порт] Три одинаковых, если два одинаковых доменных имени указывают на один и тот жеipАдреса также негомологичны. При этом адрес печатает соответствующийipОба случая также негомологичны.

Каковы ограничения политики одного и того же происхождения?

DOM-узел

дляDOMУзел может работать только под текущей открытой страницей доменаDOMСодержимое узла.

хранить информацию

дляcookie,sessionStorage,localStorage,indexedDBОжидание информации хранения и не приобретает

ajax-запрос

дляajaxПри выполнении сетевого запроса, если запрос не находится в том же домене, он будет автоматически перехвачен браузером, и будет сообщено об ошибке.

Приведите несколько примеров сценариев, вызывающих кроссдоменность?

Как упоминалось ранее, когда какой-либо протокол, имя домена и номер порта отличаются, все это является междоменным. Также включает (Разница между доменным именем первого уровня и доменным именем второго уровня) является междоменным состоянием, когда они запрашивают ресурсы друг у друга.

График междоменной адресной сцены

Каким образом можно разрешить междоменный доступ?

Может пройти принцип JSONP

Прежде всего, поймите, что когда браузер загружает ресурсы, вы можете передать:

  1. img
  2. script
  3. link

Вышеупомянутые теги разрешают междоменную загрузку ресурсов. значит вwww.baidu.comСтатический под доменным именемhtmlв файлеscriptЭтикетки могут быть загруженыwwww.google.comРесурсы скрипта под сервер и т.д.

С помощью вышеуказанных тегов мы можем загрузить понимание междоменных ресурсов, затем мы можем получить нужные данные из других доменов с помощью методов упаковки.

Расскажите о принципе реализации JSONP?

Предчувствие идеи принципа было и раньше. затем используйтеscriptОбъясняются метки, функция, позволяющая добавлять ресурсы к данным пакета между доменами.

Процесс реализации

// index.html
// jsonp的实现模拟
function jsonp({ url, params, callback }) {
  return new Promise((resolve, reject) => {
    let script = document.createElement('script')
    window[callback] = function(data) {
      resolve(data)
      document.body.removeChild(script)
    }
    params = { ...params, callback }
    let arrs = []
    for (let key in params) {
      arrs.push(`${key}=${params[key]}`)
    }
    script.src = `${url}?${arrs.join('&')}`
    document.body.appendChild(script)
  })
}

// 调用方式
jsonp({
  url: 'http://localhost:3000/getUser',
  params: { name: 'peter' },
  callback: 'user'
}).then(data => {
  console.log(data)
})

Через вышеуказанный код, основнойJSONPвызов для выполнения кода.

  1. объявить одинJSONPФункция моделирования , входные параметрыадрес запроса,параметры запроса,Имя функции-оболочки, согласованное интерфейсом и сервером., внутренне возвращаяpromiseМеханизм для элегантного решения способа возврата данных.

  2. пройти черезscriptНе существует механизма запроса ресурсов между доменами для создания одногоscriptВременная этикетка. Объедините адрес и параметры, запрошенные в фоновом режиме, вqueryФорма параметра. Адрес запроса:http://localhost:3000/getUser?name=peter&callback=user

Ключевым моментом является поместить обернутое имя функции (keyтак какcallback, valueтак какuser) имя функции-оболочки является соглашением о переднем и заднем концах.

  1. после окончательной сборкиscriptтеги вставляются вdocumentВ документе браузер автоматически инициирует запрос к целевому адресу в это время.

Принцип возврата результата в фон

// app.js 用express脚手架模拟的配合前台callback封装的返回结果

app.get('/getUser', function(req, res, next) {
  let { name, callback } = req.query
  console.log(name) // peter
  console.log(callback) // user
  res.send(`${callback}({
    code: 0,
    msg: '请求成功',
    data: {
      id: 1234
    }
  })`)
});

бэкенд пройдетqueryпараметры анализируются. Если результат, возвращаемый в это время, является объектом, объект существуетmsgсообщение, код статуса запросаcode,Информация о данныхdata.

Вы можете задаться вопросом, почему значение возвращаемого результата помещается в пользовательскую функцию выполнения. ЭтоJSONPосновной принцип. Посмотрите на этот необъяснимый фрагмент кода:

window[callback] = function(data) {
  resolve(data)
  document.body.removeChild(script)
}

При выполнении самоинкапсулированногоjsonpметод при глобальном определении функции. Это имя функции является именем пакета функций, согласованным между интерфейсом и сервером. Когда фон вернет результат, будет выполнена согласованная глобальная функция. Является ли выполнение вышеуказанного сегмента кода, параметры данных будут переданы черезresolveВыполнить возврат. Наконец удалите соответствующий запросscriptЭтикетка.

Сравнение JSONP и AJAX, в чем разница?

Тот же пункт:

JSONPа такжеajaxТо же самое, что клиент инициирует запрос к серверу.

разница:

JSONPотносятся к использованиюscriptТег сделал запрос политики другого происхождения, иajaxявляется запросом политики того же происхождения.

Преимущества и недостатки JSONP

преимущество:

JSONPПреимущество в том, что совместимость очень хорошая. потому что использованиеscriptТеги могут быть механизмами запросов разных источников. Это основная функция любого браузера.

недостаток:

только поддержкаqueryтакой параметрgetСуществуют ограничения в способе запроса и взаимодействия. также подверженxssатаку

Что делать, если серверная часть не поддерживает метод инкапсуляции JSONP?

Может общаться через сетевую технологию CORS. (полное имяCross-Orgin Resource Sharing),дляCORSЭто также требует внешнего и внутреннего сотрудничества. Но ключевым моментом является конфигурация фона. Может быть, вы подумали бы. Даже если он настраивается в фоновом режиме, необходимо полностью понять, почему стойка регистрации также должна быть полностью понята. Потому что, независимо от режима производства или разработки, междоменное взаимодействие в первую очередь оказывает наибольшее влияние на интерфейсную часть, и только при полном понимании этого серверная часть может быть выражена в серверной части для точной настройки и взаимодействия.

Простой междоменный запрос должен предложить, какие настройки следует выполнить в фоновом режиме?

Настройки имитации переднего плана

Создать локальноindex.htmlНапишите сценарий запроса. пройти черезhttp-server -p 4000начать локально4000под порт.

// index.html
let url = 'http://localhost:3000/getUser';
let xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.send();

Настройки имитации фона

пройти черезexpressФреймворк устанавливает адрес запроса, и сервис запускается локально3000под порт.

// app.js
let express = require('express')
let app = express()

app.get('/getUser', function(req, res) {
  res.send({
    code: 0,
    msg: '请求成功',
    data: {
      id: 1234
    }
  })
})

app.listen(3000)

Браузер возвращает результат

доступhttp://127.0.0.1:4000/index.htmlв состоянии пройтиNetworkКонсоль может видеть сторону браузера на заднем планеhttp://localhost:3000/getUserАдрес сервисного интерфейса делает запрос.

еслиOriginУказанный источник не входит в сферу действия лицензии, сервер вернет обычныйHTTPреагировать. Браузер обнаружил, что информация заголовка этого ответа не содержитAccess-Control-Allow-Originполе, вы знаете, что что-то пошло не так, поэтому выдается ошибка, котораяXMLHttpRequestизonerrorЗахват функции обратного вызова. Обратите внимание, что этот тип ошибки не может быть идентифицирован по коду состояния, потому чтоHTTPКод состояния ответа может быть200. Хотя вернулсяStatus CodeКод состояния200 OK,ноresponseОжидаемое значение не было возвращено в заголовке ответа. Также вconsoleКонсоль может найти:

Access to XMLHttpRequest at 'http://localhost:3000/getUser' from origin 'http://127.0.0.1:4000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

CORSПолитика запрещаетhttp://127.0.0.1:4000доступhttp://localhost:3000/getuserкудаXMLHttpRequest: Нет на запрошенном ресурсе'Access- control - allow-origin'голова.

это самый простойCORSполитика безопасности, из отчета об ошибке очевидно, что вам нужно указать фон, который вам нужно установить'Access- control-allow-origin'голова.

Серверные решения

// app.js中添加

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*')
  // res.setHeader('Access-Control-Allow-Origin', req.headers.origin)
  next()
})

Выполните слой фильтрации промежуточного программного обеспечения при получении запроса. Можно использовать любой из следующих методов.

  1. Установите заголовок ответа при возвратеAccess-Control-Allow-Originдля*(Запросы к текущей службе от имени всех доменов разрешают междоменный доступ)
  2. Установите заголовок ответа при возвратеAccess-Control-Allow-Originдля указанного доменного имени. Никакие другие доменные имена не разрешают междоменный доступ

Установка заголовка Access-Control-Allow-Origin решает все междоменные проблемы?

Access-Control-Allow-OriginНастройка заголовка может решать только простые междоменные запросы.

Простые условия междоменного запроса:

Условие 1: разрешены только следующие методы запроса

  • GET
  • HEAD
  • POST

Условие 2:Content-Typeразрешить условия

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

Условие 3: не может превышатьhttpСледующие поля информации заголовка

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID

Как решить другие запросы? Что это за запрос о перекрестном происхождении?

Другие методы запроса называются сложными запросами между источниками. Если он не соответствует простой политике междоменных запросов, это сложный междоменный запрос:

Объяснение сложных запросов между источниками:

  1. В дополнение к простому перекрестному домену. НапримерPUT,DELETE
  2. Помимо простых междоменных запросовContent-typeТипы. Напримерapplication/json
  3. индивидуальныеheaderголова
  4. под разными доменамиcookieкоробка передач

Попробуйте решить несколько ситуаций сложных междоменных

1. Методы запросов, такие как put и delete, вызывают сложные запросы

// 修改请求方法
- xhr.open('get', url, true);
+ xhr.open('put', url, true);
// 修改后台接收请求方法
app.put('/getUser') // 省略... 对于后台只是把get请求换成put接收请求

в браузереnetWorkнашел и не отправилputзапрос, вGeneralсерединаRequest Methodобнаружил, что отправилOPIONSпредварительный запрос (Что касается предварительной проверки, соответствующие подробные точки знаний будут специально представлены при решении междоменной проблемы путем закрытия стратегии браузера.)

При этом в браузере будет выдано сообщение об ошибке:

Access to XMLHttpRequest at 'http://localhost:3000/getUser' from origin 'http://127.0.0.1:4000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

решение:

// 在app.use中添加新的设置头
// res.setHeader('Access-Control-Allow-Methods', '*')
res.setHeader('Access-Control-Allow-Methods', 'PUT')

Полученные выше настройки позволяют разрешить следующие методы запроса:

  • настраивать*, указывающий, что разрешены все методы запроса.
  • Укажите соответствующие методы запроса через запятую.

2.content-type вызывает сложные запросы

+ xhr.setRequestHeader('content-type', 'application/json');

Прежде чем говорить о простом условии междоменного запроса два, оcontent-typeДля простых запросов между источниками поддерживаются только три типа. Установка других приведет к сложным запросам между источниками. когда установленоcontent-type: application/json, тот же браузер выдаст сообщение об ошибке:

Access to XMLHttpRequest at 'http://localhost:3000/getUser' from origin 'http://127.0.0.1:4000' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

Из сообщения об ошибке видно, что фон должен выполнять сложные междоменные запросы.content-typeСделайте дополнительную настройку:

// 在app.use中添加新的设置头
+ res.setHeader('Access-Control-Allow-Headers', 'content-type')

3. Пользовательские заголовки вызывают сложные запросы

+ xhr.setRequestHeader('X-Customer-Header', 'value');

В предыдущем обсуждении условия простого междоменного запроса три, в дополнение к приведенному вышеhttpПосле заголовка запроса он принадлежит пользовательскому заголовку. Когда запрос будет внесен, он вызовет сложный междоменный запрос, и тот же браузер выдаст сообщение об ошибке.

Access to XMLHttpRequest at 'http://localhost:3000/getUser' from origin 'http://127.0.0.1:4000' has been blocked by CORS policy: Request header field x-customer-header is not allowed by Access-Control-Allow-Headers in preflight response.

Тот же принцип применяется к пользовательским заголовкам, установленным передним планом, и фон также может устанавливать пользовательские заголовки, передаваемые передним планом при получении.

res.setHeader('Access-Control-Allow-Headers', 'content-type, X-Customer-Header')
// res.setHeader('Access-Control-Allow-Headers', '*')

существуетAccess-Control-Allow-HeadersПри настройке вы можете установить несколько пользовательских заголовков, разделенных запятыми. Его также можно передать в*, разрешая любые пользовательские заголовки.

Расскажите о файлах cookie в CROS?

В случае абсолютного же домена

В случае абсолютной гомологии. Когда интерфейс запрашивает интерфейс или файл у сервера, он автоматическиcookieв заголовок запроса.

в непохожем случае

в неколокализованных ситуациях. Нужно использоватьCORSстратегия передачи. по умолчанию,cookieВ шапку запроса его не занесут, нужноxhrУстановите учетные данные запроса.

xhr.withCredentials = true

Простой междоменный запрос с файлами cookie

Если в настоящее время это простой междоменный запрос, установитеwithCredentials = trueна случай, если. будет включен в заголовок запросаcookieинформацию, фон получает запрос и отправляет его на передний план, в это время браузер запускается сresponseВы видите, что данные были возвращены, но данные, возвращенные фоном, не могут быть получены, потому что в это время они будутxhrОшибка зафиксирована, и в консоли браузера появится следующее приглашение:

Access to XMLHttpRequest at 'http://localhost:3000/getUser' from origin 'http://localhost:4000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

сложные междоменные запросы

Если в настоящее время это сложный междоменный запрос, установитеwithCredentials = trueна случай, если. отправитOPTIONSпросить. Сообщение об ошибке, отправленное браузером, по-прежнему такое же, как и простая ошибка междоменного запроса.

решение

В это время стойка регистрации отправляетcookieУчетные данные, тот же сервер должен согласиться на получение учетных данных.

res.setHeader('Access-Control-Allow-Credentials', true)

Обратный принцип:

Если серверная часть соглашается получить учетные данные. В случае, если стойка регистрации не настроена на отправку учетных данных. Даже если он установлен в заголовке ответа, отправленного из фона на передний планcookieИнформация(заголовок set-cookie), будь то простой запрос из разных источников или сложный запрос из разных источников, приведет кcookieВставка недействительна, вы можете проверитьappliation/cookie, не будет фоновой записиcookieИнформация.

придерживаться политики одинакового происхождения

По вопросам безопасности.cookieПо сути, сохраняется та же модель политики. После того, как учетные данные отправки/получения установлены во внешнем и внутреннем интерфейсе, для возвращаемыхoriginнастройки заголовкаres.setHeader('Access-Control-Allow-Origin', '*')не может быть*, необходимо установить, чтобы указать источник запросаres.setHeader('Access-Control-Allow-Origin', req.headers.origin).

Допустимые и недопустимые комбинации.

когда установленоCredentialsКогда бэкэнд должен знатьAccess-Control-Allowдопустимые и недопустимые комбинации. однаждыAccess-Control-Allow-CredentialsУстановить какtrueКогда , следующее не может быть установлено как*, необходимо указать, в противном случае следующие три скорости считаются недействительными настройками.

  • Access-Control-Allow-Headers
  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods

Как получить информацию в заголовке ответа в xhr в случае CORS?

в состоянии пройтиxhr.getResponseHeaderспособ получения. Но этот метод может получить только 6 основных полей:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma.

При ответе в фоновом режиме вы можете запихнуть некоторые пользовательские заголовки и значения в заголовки ответа.

res.setHeader('name', 'peter')

Вы можете увидеть в сообщении тела ответа:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type, X-Customer-Header
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Origin: http://localhost:4000
Connection: keep-alive
Content-Length: 50
Content-Type: application/json; charset=utf-8
Date: Sun, 17 Feb 2019 08:18:08 GMT
ETag: W/"32-oUKytSTXnBL0hnySFj9PpHgmBQk"
name: peter   // 重点在这里
X-Powered-By: Express

В сообщении вы можете найти много информации, возвращенной из предыдущих настроек фона, и наиболее важную информацию здесь.nameИнформация заголовка. Но после тестирования следующими методами заключение:

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.getResponseHeader('Content-Type'))
      console.log(xhr.getResponseHeader('name'))
    }
  }
}

существуетxhrПосле успешного возвращения. Получите две информации заголовка соответственно.

  • Content-Typeвернусьapplication/json; charset=utf-8

  • nameподскажетсообщение об ошибке, и возвращаетсяnullНулевое значение.

Refused to get unsafe header "name" // 拒绝获取不安全的头信息“name”

Понятно, что в дополнение к вышеупомянутым шести типам информации заголовков, которые можно получить, все остальные должны быть установлены в фоновом режиме, чтобы разрешить доступ к этим заголовкам ответов.

res.setHeader('Access-Control-Expose-Headers', 'name')

В это время сообщения об ошибке в браузере не будет, и его также можно будет распечатать.nameзначение в заголовке ответа.УведомлениеЕсли установленное значение*является недействительным. Необходимо установить указанный заголовок поля.

Сложный междоменный запрос приведет к отправке запроса OPTIONS для каждого запроса. Как решить эту проблему?

Из всего приведенного выше анализа сложных междоменных запросов ясно видно, что эти методы запроса вызывают отправку предварительных проверок.В одном предложении заголовок ответа **Access-Control-Max-Age указывает на предварительный запрос ( запрос предварительной проверки) Как долго возвращаемые результаты (то есть информация, предоставленная методами Access-Control-Allow-Methods и Access-Control-Allow-Headers) могут кэшироваться. **Вот такnetworkНедружелюбно требовать наблюдения и производительности в . Если это дружественный и безопасный механизм.

Сделать срок действия запроса времени для предполетной проверки

res.setHeader('Access-Control-Max-Age', 600)

Настройки для предварительных запросов10Срок действия в минутах (время может быть настроено в зависимости от ситуации с проектом). Но механизм времени кеша различен для каждого браузера. При локальной отладке иногда вы обнаружите, что время истечения срока действия, установленное для предварительной проверки, не действует.Обратите внимание, что по этой причине может быть включен параметр «Отключить кеш» в браузере.

Когда задний конец переднего ФБР, а не через внутренние настройки, как решить междоменные проблемы?

Отключите междоменную политику браузера.

Согласно предыдущему анализу, весь междоменный режим вызван действиями внешнего браузера. В целях безопасности браузеры выполняют серию проверок междоменных запросов. Можно ли подумать, можно ли решить принципиальную проблему, отключив вручную междоменную политику браузера.

Mac создает файл chrome.sh

#!/bin/bash
#!/bin/sh

open -a "Google Chrome" --args --disable-web-security  --user-data-dir

exit 0

Запустить через терминал:

sh 加上chrome.sh文件地址

Уведомление: При запуске команды терминала сначала проверьте, запущена ли онаchrome, если он был запущен, вам нужно вручную закрыть весьchromeобработать.

Успешный результат:

войтиURLпосле адреса. Все междоменные вопросы будут решаться вместе.

принцип

Хотя междоменная политика браузера отключена. При просмотре не передается междоменное поведение, и его внутренний принцип заключается именно в том, что браузер перехватывает простые междоменные запросы и предварительно проверяет сложные междоменные запросы.

Что такое перехват простых междоменных запросов?

Чтобы разобраться в простом междоменном запросе, сначала нужно разобраться в полях двух заголовков запроса.

Происхождение в заголовке запроса

поля заголовка запросаOriginУказывает, с какого сайта пришел запрос. В этом поле указывается только имя сервера и не содержится никакой информации о пути. Этот заголовок используется дляCORSпросить.

Проще говоря, он сообщает серверу, что в данный момент он отправлен с адреса доменного имени. только вCORSна случай, еслиOriginпоявится в заголовке запроса.

HOST в заголовке запроса

HostВ заголовке запроса указывается доменное имя сервера (для виртуальных хостов) и (необязательно) номер TCP-порта, на котором сервер прослушивает. Если номер порта не указан, автоматически используется порт по умолчанию для запрошенной службы (например, запрос наHTTPизURLбудет использоваться автоматически80порт).HTTP/1.1Все пакеты запросов должны содержать поле заголовка Host. еслиHTTP/1.1Запрос отсутствуетHostполе заголовка или установить более одногоHostполя заголовка, а400(Bad Request) будет возвращен код состояния.

С точки зрения непрофессионала, это адрес доменного имени запрошенного сервера, когда браузер отправляет запрос на сервер.

Access-Control-Allow-Origin в заголовке ответа

Заголовок ответа указывает, разрешено ли ресурсу ответа соответствовать ресурсу, указанному в заголовке запроса переднего плана.originобщий.

В заключение

Таким образом, после того, как междоменный запрос возвращается в браузер. Хотя данные будут возвращены, но. Браузер сравнит заголовок запросаOriginс заголовком ответаAccess-Control-Allow-OriginЯвляется ли это общим совпадением, если нет. браузерxhrОшибки перехватываются и выбрасываются в консоль браузера. Ожидаемые данные не могут быть получены.

Как браузер сложных запросов обнаруживает кросс-происхождение?

Для сложных междоменных запросов, как только браузер обнаружит, что отправленный заголовок запроса является сложным междоменным запросом, он сначала отправит предварительный запрос, а заголовок запроса содержит следующее важное содержимое:

  1. Access-Control-Request-Headers(если есть пользовательские заголовки илиcontent-typeТолько когда тип не относится к типу простого запроса)
  2. Access-Control-Request-Method(За исключением простых методов запроса)

А при отправке предварительного запроса данные запроса иcookieИнформация переносится в информацию запроса.

Что такое предварительный запрос?

существуетCORSбудет использоваться вOPTIONSметод инициирует предварительный запрос (preflight request), чтобы узнать, разрешает ли сервер фактический запрос. Использование «предварительного запроса» может предотвратить неожиданное влияние междоменных запросов на пользовательские данные сервера.

При отправке в заголовке запроса браузераrequest-Headerилиrequest-MethodВремя.此时服务端需要同意这两个请求头中对应的信息通过允许。需要在响应返回的时候对响应头做出响应处理。 нужноAccess-Control-Allow-Methodsа такжеAccess-Control-Allow-Headersнастраивать.

Схема:

случайныйCredentialsЯвляется ли запрос (для учетных данных) простым запросом из разных источников или сложным запросом из разных источников?

оCredentialsсуществуетCORSПринцип нейтральности уже разъяснен очень ясно. Но что я хочу сказать здесь, так это то, чтоxhrсерединаCredentialsУстановить какtrueВремя. В настоящее время это всего лишь простой междоменный запрос, и предварительная проверка не будет отправлена ​​(OPTIONS) запрос, если в настоящее время это сложный запрос из разных источников. отправит предварительную проверку (OPTIONS)просить.

такCredentialsОтправлять ли предварительную проверку в основном зависит от суждения других заголовков запроса, чтобы решить, следует ли отправлять предварительную проверку.

Схема:

Суммировать:

только тогда, когдаrequestзаголовок запроса сresponseВернемся к главе Индивидуальная переписка. Разрешить друг другу с помощью общих политик. Для простых запросов из разных источников ошибки не будут обнаружены, для сложных запросов из разных источников отправляются настоящие запросы. будет такжеcookieПодождите, пока данные передачи будут внесены в тело запроса. Таким образом, закрытие междоменной политики браузера означает закрытие ответа браузера наOriginПри совпадении заголовка он больше не будет захватываться, а также закроет соответствующийOPTIONSЗапрос перед полетом. Отправить непосредственно на соответствующий фоновый сервер. Так что по сути, хоть и есть междоменность, но сервер всегда возвращает данные. Что-то не так или не отправка реального запроса - это механизм безопасности браузера.

Как решить проблему междоменного доступа через механизм захвата прокси?

Мы уже знаем, что междоменная проблема возникает, когда браузер запрашивает сервер, но междоменная проблема отсутствует, когда сервер отправляет запрос на сервер. пройти черезMS(middle server)После перехвата запроса запрос отправляется на сервер через сервер, а затем снова возвращается в браузер.

Схема:

Начал с скаффолдинга во всех основных фреймворкахnodeУслуги хост-проектов. Напримерvue-cliиспользуется вhttp-proxy-middleВыполняйте прокси-перехват запросов и отправляйте запросы на целевой сервер для решения междоменных проблем.

// 通过express启用3000端口

// index.html
<script>
  let url = '/api/getUser';
  let xhr = new XMLHttpRequest();
  xhr.open('post', url, true);
  xhr.setRequestHeader('content-type', 'application/json');
  xhr.setRequestHeader('X-Customer-Header', 'value');
  xhr.send();
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
        console.log(1)
        console.log(xhr.response)
      }
    }
  }
  
</script>


const proxyOption = {
	target: 'http://localhost:4000',
	pathRewrite: {
        '^/api/' : '/'  // 重写请求,api/解析为/
    },
    changeOrigin:true
};

app.use('/api', proxy(proxyOption))

// 后台服务启动4000端口
app.post('/getUser', (req, res, next) => {
  res.send({
    code: 1
  })
})

когда3000Порт отправки статического файлаajaxКогда запрос сделан, он находится под доменным именем, это не вызовет междоменных проблем и будетapp.use('/api/')захват перехвата при перезаписиurlадрес к серверу4000Клиент делает запрос на отправку данных. В это время этоserverзакончить сserverсвязь запроса терминала. когда4000портserverПолучив запрос, верните данные в3000портserverзакончить, а затем вернуться к запрашивающемуajax.

Как использовать собственный API узла?

app.use('/api', (req, res) => {
  const reqHttp = http.request({
    host: '127.0.0.1',
    path: '/getUser',
    port: '4000',
    method: req.method,
    headers: req.headers
  }, (resHttp) => {
    let body = ''
    resHttp.on('data', (chunk) => {
      console.log(chunk.toString())
      body += chunk
    });
    resHttp.on('end', () => {
      res.end(body)
    });
  })
  reqHttp.end()
});

Приведенный выше код по сути имитирует способ захвата прокси, и при перехватеurlначинается с/apiПосле первоначального запроса черезnodeРоднойhttpмодульныйrequestМетод отправляет запрос на соответствующий фон, и в то же время отправляет некоторые тела запроса, заголовки запроса и другие данные, запрошенные браузером, наserverконец. пройти черезhttpКонечный метод мониторинга модуля, наконец, возвращает данные вclientсторона браузера. Таким образом формируется вторичный метод передачи для решения междоменной проблемы. Суть в том, чтобы использовать сервер для отправки запросов службе без ограничения междоменной политики, которая является так называемой политикой одного и того же происхождения. потому что браузер сделаетoptionsДождитесь обнаружения предпечатной проверки, но сервер не будет.