Fetch() не отправляет заголовки?
Я отправляю запрос POST, как это из браузера:
fetch(serverEndpoint, {
method: 'POST',
mode: 'no-cors', // this is to prevent browser from sending 'OPTIONS' method request first
redirect: 'follow',
headers: new Headers({
'Content-Type': 'text/plain',
'X-My-Custom-Header': 'value-v',
'Authorization': 'Bearer ' + token,
}),
body: companyName
})
К моменту, когда запрос достигнет моего back-end, он не содержит заголовок X-My-Custom-Header
и Authorization
.
My back-end - это функция Google Cloud для Firebase (в основном только конечная точка Node.js), которая выглядит следующим образом:
exports.createCompany = functions.https.onRequest((req, res) => {
let headers = ['Headers: ']
for (let header in req.headers) {
headers.push(`${header} : ${req.headers[header]}`)
}
console.log(headers)
...
}
Консольный журнал этой функции Google Cloud для Firebase не содержит заголовка X-My-Custom-Header
и Authorization
.
Что не так?
Изменить 1
Поэтому, используя инструменты dev в Chrome, проверено, что ни один X-My-Custom-Header
и Authorization
заголовок не отправляется из браузера... Теперь вопросы: почему? Как это исправить?
Изменить 2
Дополнительная информация о моем приложении: приложение React React. У меня отключен рабочий службы. Я попытался создать Request
и специально добавить заголовки с помощью req.headers.append()
. Заголовки все равно не отправили.
Ответы
Ответ 1
политика одинакового происхождения ограничивает типы запросов, которые веб-страница может отправлять на ресурсы из другого источника.
В no-cors
mode браузер ограничивается отправкой "простых" запросов - те, у кого безопасные методы и сохраненные заголовки.
Чтобы отправить запрос с кросс-началом с заголовками, такими как Authorization
и X-My-Custom-Header
, вам нужно отказаться от режима no-cors
и запросить предварительные предпрограммы (OPTIONS
).
Различие между "простыми" и "непростыми" запросами носит исторический характер. Веб-страницы всегда могли выполнять некоторые запросы с перекрестным происхождением различными способами (например, создавать и отправлять форму), поэтому, когда веб-браузеры вводили принципиальное средство отправки запросов с перекрестным происхождением (совместное использование ресурсов в разных источниках или CORS) было решено, что такие "простые" запросы могут быть освобождены от проверки предпросмотра OPTIONS
.
Ответ 2
Во-первых: используйте объект вместо new Headers(..)
:
fetch('www.example.net', {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
'X-My-Custom-Header': 'value-v',
'Authorization': 'Bearer ' + token,
}
});
Во-вторых,. Полезно знать, заголовки находятся внизу fetch
!!
Режим Thridly: no-cors
ограничить использование заголовков в этом белом списке:
-
Accept
-
Accept-Language
-
Content-Language
-
Content-Type
и значение которого (application/x-www-form-urlencoded
, multipart/form-data
, text/plain
)
Вот почему отправляется только ваш Content-Type
заголовок, а не X-My-Custom-Header
или Authorization
.
Ответ 3
Вы можете попробовать это?
fetch(serverEndpoint, {
credentials: 'include'
})
Ref. https://developers.google.com/web/updates/2015/03/introduction-to-fetch#sending_credentials_with_a_fetch_request
Ответ 4
1st: при вызове заголовков в вашей функции export.createCompany у вас есть let headers = ['Headers: ']
с капиталом H
вместо строчного H
, который может вызвать ошибки. у вас также есть запятая после токена в заголовках, которые не должны быть там.
2nd: каждый раз, когда я использовал запросы выборки в реакции native, header:
не нуждается в new Headers
на нем.
попробуйте следующее: fetch(serverEndpoint, {
method: 'POST',
mode: 'no-cors',
redirect: 'follow',
headers:{
'Content-Type': 'text/plain',
'X-My-Custom-Header': 'value-v',
'Authorization': 'Bearer ' + token
},
body: companyName
})