fetch () не надсилає заголовки?


77

Я надсилаю такий запит 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
})

На той час, коли запит доходить до мого інтерфейсу, він не містить X-My-Custom-Headerані Authorizationзаголовка.

Мій бек-енд - це функція 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

Тож за допомогою інструментів розробника в Chrome перевірено, що ні браузер, X-My-Custom-Headerні Authorizationзаголовок не надсилаються ... Зараз питання: Чому? Як це виправити?


Редагувати 2

Більше інформації про мою програму: це програма React. У мене працівник служби з обмеженими можливостями. Я намагався створювати Requestта спеціально додавати заголовки за допомогою req.headers.append(). Заголовки все одно не надсилатимуть.


1
Ваш браузер насправді надсилає заголовки? Перевірте свої інструменти розробника.
Джо Клей,

@JoeClay Я досвідчений розробник (мобільний, серверний), але досить новий у веб-інтерфейсній розробці. Багато інструментів для мене нові - особливо інструменти розробників у brownser ще не дуже хороший мій друг. Чи можете ви підказати, як це перевірити в Chrome або Safari? Дякую
Расто

2
У Chrome натисніть F12, щоб відкрити інструменти розробника, а потім перейдіть на вкладку Мережа. Коли ваша програма надсилає запит HTTP, він з’явиться у списку, і ви можете натиснути на нього, щоб переглянути заголовки / тіло запиту та відповідь. Перегляньте документи для отримання додаткової інформації - навчитися користуватися розробницькими інструментами вашого браузера допоможе вам завантажити файли, якщо ви тільки починаєте розробку веб-сайтів :)
Джо Клей,

1
@JoeClay Отже, відповідь - ні браузер не надсилає, X-My-Custom-Headerні Authorization. Тепер залишилися питання чому? І як це виправити?
Расто

Відповіді:


113

Політика того самого походження обмежує типи запитів, які веб-сторінка може надсилати до ресурсів іншого походження.

У цьому no-cors режимі браузер обмежується надсиланням "простих" запитів - лише тих, що мають безпечні методи та заголовки .

Щоб надіслати запит на перехресне походження із заголовками типу Authorizationі X-My-Custom-Header, вам слід відмовитись від no-corsрежиму та підтримати передпольотні запити ( OPTIONS).

Різниця між "простими" та "не простими" запитами полягає в історичних причинах. Веб-сторінки завжди можуть виконувати деякі запити про перехресне походження за допомогою різних засобів (наприклад, створення та подання форми), тому, коли веб-браузери запровадили принциповий спосіб надсилання запитів про перехресне походження (спільне використання ресурсів або CORS), це було вирішив, що такі “прості” запити можуть бути звільнені від передпольотичної OPTIONSперевірки.


3
Чудова відповідь, дякую. Однак не та відповідь, яка зробила б мене щасливим. Зараз я намагаюся додати підтримку для CORS.
Расто,

@sideshowbarker так, точно. Це є. Просто добре підтримувати CORS, здається, не дуже просто
Расто,

1
@sideshowbarker Погляньте на мій профіль, його вік, значки та старіші запитання. З цього ви повинні зрозуміти, що я знаю, про що я просив, і як позначити, що приймається, дякую. Якщо ви дійсно хочете порадити іншим, що робити з відповідями та нагородами, ви можете зробити це на мета. Щодо цієї відповіді, я можу позначити її як прийняту лише після того, як на сервері підтримується CORS. Без цього я не маю доказів того, що це справді працює (а 500 - це багато повторень, які потрібно витратити на неправильну відповідь). Крім того, як ви повинні знати, я не зобов’язаний позначати це як прийняте, навіть якщо це працює, оскільки я можу чекати більше / кращих відповідей.
Расто,

Вищезазначене, щоб уникнути непорозуміння: мені дуже подобається відповідь Василя, оскільки він є якісним, і, швидше за все, його приймуть, якщо він спрацює, коли я отримаю підтримку CORS, яка працює на задній панелі (функції Firebase).
Расто,

1
stackoverflow.com/questions/42755131/… Це може допомогти.
CaptainHere

24

По-перше : Використовуйте об’єкт замість new Headers(..):

fetch('www.example.net', {
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
    'X-My-Custom-Header': 'value-v',
    'Authorization': 'Bearer ' + token,
  }
});

По-друге : корисно знати, заголовки мають нижній регістр fetch!!

По-третє : 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.



2

У мене теж була така сама проблема. Я вирішив це, видаливши "no-cors" з javascript і додавши наступне у весняному завантаженні на стороні сервера.

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity httpSecurity) throws Exception {
             .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

        }
    }

Чи не вистачає цього коду? Як тіло методу може починатися з "."? Це має бути HttpSecurity.?
GreenAsJade

0

По-перше: коли ви викликаєте заголовки у своїй функції export.createCompany, у вас є let headers = ['Headers: ']велика Hлітера, а не мала літера, hщо може спричинити помилки. у вас також є кома після маркера в заголовках, яких там не повинно бути.

2-е: кожного разу, коли я використовував запити на отримання в рідній реакції, 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
})

примітка про кінцеву кому, яка стає стандартом - це ES2017, але люди використовують її з Babel ( babeljs.io/docs/plugins/syntax-trailing-function-commas ), а також NodeJS підтримує її з версії 6.4.0. Це не повинно впливати на операційну програму, оскільки я fetch()раніше успішно використовував кінцеві коми .
Sgnl

Ця відповідь не стосується ні першого, ні другого питання. Він просто дає деякі виправлення синтаксису.
pungggi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.