Совместное использование ресурсов между источниками — это механизм, который использует дополнительные заголовки HTTP, чтобы сообщить браузеру, что веб-приложение может выполнять запросы ресурсов из разных источников.
тип запроса
простой запрос
если запросУдовлетворить всем следующим условиям одновременно, запрос можно рассматривать как "простой запрос"(Примечание: содержимое серого шрифта можно понять):
- Используемый метод
GET
HEAD
POST
- Поля заголовков, заданные вручную, могут быть только (Примечание: также могут быть установленыForbidden header nameполя заголовка в
Connection
,Accept-Encoding
д., но настройка не влияет)Accept
Accept-Language
Content-Language
-
Content-Type
(Диапазон значений также должен соответствовать следующим требованиям) -
`DPR`
-
`Downlink`
-
`Save-Data`
-
`Viewpoer-Width`
-
`Width`
-
Content-Type
Значение может быть толькоapplication/x-www-form-urlencoded
multipart/form-data
text/plain
-
No event listeners are registered on any `XMLHttpRequestUpload` object used in the request; these are accessed using the XMLHttpRequest.upload property.
-
No ReadableStream object is used in the request.
предварительный запрос
Запрос предварительной проверки CORS выполняется перед фактическим запросом и используется для проверки того, поддерживает ли сервер CORS, чтобы определить, безопасно ли отправлять фактический запрос. Предварительный запрос используется следующим образом:OPTIONS
.
Если запрос не является «простым запросом», сначала следует отправить предварительный запрос, например:
- Метод запроса для этого запроса не
GET
,HEAD
,POST
- В качестве альтернативы запрос устанавливает настраиваемые поля заголовка, такие как
X-xxx
- или этот запрос
Content-Type
значение неapplication/x-www-form-urlencoded
,multipart/form-data
,text/plain
,так далее
Процесс запроса между источниками
Для междоменных запросов CORS требует, чтобы сервер установил некоторые поля заголовка, наиболее важным из которых являетсяAccess-Control-Allow-Origin
. Ниже приведен пример, иллюстрирующий использование внешнего интерфейса.axiosДля передачи http серверная часть начинается сkoaВ качестве серверной среды и использования промежуточного программного обеспечения CORS.koa2-cors.
Простой междоменный запрос
// Client http://localhost:8080
simpleRequest() {
axios({
method: 'GET',
url: 'http://localhost:3000/api/simple'
}).then(data => {
console.log(data);
});
}
// Server http://localhost:3000
app.use(cors());
router.get('/api/simple', ctx => {
ctx.body = { result: 'simple request success' };
});
HTTP-сообщение:
Заголовок HTTP-запроса имеетOrigin
Поле, указывающее, откуда пришел запрос. в заголовке ответа HTTPAccess-Control-Allow-Origin
Указывает, какой домен может получить доступ к ресурсу. использоватьOrigin
а такжеAccess-Control-Allow-Origin
На этом простейший контроль доступа завершен.
Предварительный запрос и официальный запрос
// Client http://localhost:8080
mainRequest() {
axios({
method: 'POST',
url: 'http://localhost:3000/api/mainRequest',
headers: { 'X-test': 'CORS' } // 增加一个自定义的头部字段,触发预检请求
}).then(data => {
console.log(data);
});
}
// Server http://localhost:3000
app.use(cors());
router.post('/api/mainRequest', ctx => {
ctx.body = { result: 'main request success' };
});
Сообщение предполетного запроса:
поля заголовка запросаAccess-Control-Request-Method
сообщить серверу, что фактический запрос будет использоватьPOST
метод.
поля заголовка запросаAccess-Control-Request-Headers
Сообщите серверу, что фактический запрос будет содержать пользовательское поле заголовка запроса: x-test. На основании этого сервер решает, разрешен ли фактический запрос.
поля заголовка ответаAccess-Control-Allow-Methods
Указывает, какие методы сервер разрешает клиентам использовать для выполнения запросов.
поля заголовка ответаAccess-Control-Allow-Headers
Указывает, что сервер разрешает перенос поля x-test в запросе.
Фактическое сообщение запроса:
отправлено в фактическом запросеX-test
Поле заголовка, код состояния ответа 200 OK.
Видно, что клиент и сервер используют больше полей заголовка в предварительном запросе для полного контроля доступа. Итак, что такое поля заголовка запроса и поля заголовка ответа, связанные с CORS?
поле заголовка
Поля заголовка HTTP-запроса
-
Origin
Origin
Поле заголовка указывает происхождение запроса предварительной проверки или фактического запроса. -
Access-Control-Request-Method
Access-Control-Request-Method
поля заголовка используются дляпредварительный запрос. Его роль состоит в том, чтобы сообщить серверу, какой метод HTTP использовался для фактического запроса. -
Access-Control-Request-Headers
Access-Control-Request-Headers
поля заголовка используются дляпредварительный запрос. Его роль состоит в том, чтобы сообщить серверу поля заголовка, содержащиеся в фактическом запросе.
Обратите внимание, что приведенные выше поля заголовка запроса не нужно задавать вручную при использованииXMLHttpRequest
Когда объекты делают запросы между источниками, они уже настроены.
Поля заголовка ответа HTTP
-
Access-Control-Allow-Origin
Его синтаксис следующий:Access-Control-Allow-Origin: <origin> | *
Значение параметра origin указывает URI внешнего домена, которому разрешен доступ к ресурсу. Если значение поля является подстановочным знаком
*
, что означает, что запросы от всех доменов разрешены.
Обратите внимание, что если сервер указывает конкретное доменное имя вместо*
, то заголовок ответаVary
Значение поля должно содержатьOrigin
. Это сообщит клиенту: сервер возвращает разный контент для разных источников. -
Access-Control-Allow-Methods
Access-Control-Allow-Methods
Поля заголовка используются для ответов на предварительные запросы. Он указывает методы HTTP, разрешенные для фактического запроса. -
Access-Control-Allow-Headers
Access-Control-Allow-Headers
Поля заголовка используются для ответов на предварительные запросы. Он определяет поля заголовка, которые разрешено использовать в фактическом запросе. -
Access-Control-Expose-Headers
В запросе из другого источника браузер по умолчанию может получить через API только следующие поля заголовка ответа:Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
Если вы хотите получить доступ к другой информации заголовка ответа, вам необходимо установить ее на стороне сервера.
Access-Control-Allow-Headers
.Access-Control-Expose-Headers
Пусть сервер внесет в белый список поля заголовков, к которым разрешен доступ браузерам, например:Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Браузер может получить доступ
X-My-Custom-Header
а такжеX-Another-Custom-Header
заголовки ответов. -
Access-Control-Max-Age
Access-Control-Max-Age
Поле указывает, как долго результаты предварительного запроса могут кэшироваться, в единицахВторой,Например:Access-Control-Max-Age: 5
Указывает, что после отправки первого запроса предварительной проверки фактический запрос будет отправлен непосредственно при повторном доступе к интерфейсу в течение 5 с, без необходимости предварительной отправки запроса предварительной проверки. Через 5 секунд он попросит сначала отправить предварительный запрос и так далее.
app.use( cors({ maxAge: 5 }) );
Сервер устанавливает 5-секундный кеш, и фактический запрос выглядит следующим образом:
Обратите внимание: если вы обнаружите, что запрос OPTIONS по-прежнему отправляется каждый раз после настройки кеша, проверьте, не поставили ли вы флажок «Запретить кеширование».
-
Access-Control-Allow-Credentials
XMLHttpRequest.withCredentials
(илиRequest.credentials
) указывает, должен ли пользовательский агент отправлять учетные данные, такие как файлы cookie, заголовки авторизации или сертификаты клиента TLS, в запросах между источниками.Access-Control-Allow-Credentials
Функция такова: когда учетные данные «истинны» (XHR и Fetch установлены по-разному),Access-Control-Allow-Credentials
Сообщите браузеру, следует ли предоставлять содержимое ответа внешнему JS-коду. Например:// Client http://localhost:8080 simpleRequest() { axios({ method: 'GET', url: 'http://localhost:3000/api/simple', withCredentials: true // 增加了withCredentials 选项 }).then(data => { console.log(data); }); } // Server http://localhost:3000 app.use( cors({ maxAge: 5, // credentials: true }) );
На данный момент сервер не установлен
credentials: true
, вы можете увидеть, как клиент сообщает об ошибке, когда вы инициируете запрос:Если сервер установлен
credentials: true
Тогда клиент не сообщит об ошибке.При предварительной проверке запросов
Access-Control-Allow-Credentials
Поле заголовка ответа указывает, можно ли использовать учетные данные в фактическом запросе.
Что касается использования полей заголовка ответа CORS, рекомендуется взглянутьkoa2-corsИсходный код промежуточного программного обеспечения. Код состоит всего из нескольких десятков строк, и он очень понятен и прост для понимания.
Соответствующее содержание CORS указано выше.После понимания это может лучше помочь нам решить проблемы при ежедневной совместной отладке, такие как: как настроить сервер при возникновении междоменного взаимодействия,axios.post
Почему появляется запрос OPTIONS, когда метод отправляет объект, как прокси-сервер может пересылать куки и т.д.