fetch () sendet keine Header?

75

Ich sende eine POST-Anfrage wie folgt vom Browser:

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
})

Bis die Anfrage mein Back-End erreicht, enthält sie X-My-Custom-Headerweder einen AuthorizationHeader noch einen Header.

Mein Backend ist die Google Cloud-Funktion für Firebase (im Grunde nur der Endpunkt von Node.j), die folgendermaßen aussieht:

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)
    ...
}

Das Konsolenprotokoll dieser Google Cloud for Firebase-Funktion enthält weder einen Header X-My-Custom-Headernoch einen AuthorizationHeader.

Was ist falsch?


Bearbeiten 1

Wenn Sie also Entwickler-Tools in Chrome verwenden, wird überprüft, ob weder X-My-Custom-Headernoch AuthorizationHeader vom Browser gesendet werden. Die Fragen lauten nun: Warum? Wie behebe ich das?


Bearbeiten 2

Weitere Informationen zu meiner App: Es ist React App. Ich habe einen Servicemitarbeiter mit Behinderung. Ich habe versucht, RequestHeader mit zu erstellen und spezifisch hinzuzufügen req.headers.append(). Die Header würden immer noch nicht senden.

Rasto
quelle
1
Sendet Ihr Browser tatsächlich die Header? Überprüfen Sie Ihre Entwickler-Tools.
Joe Clay
@ JoeClay Ich bin ein erfahrener Entwickler (Mobile, Backend), aber ziemlich neu in der Web-Front-End-Entwicklung. Viele Tools sind neu für mich - besonders Entwickler-Tools in Brownser sind noch keine sehr guten Freunde von mir. Können Sie vorschlagen, wie ich es in Chrome oder Safari überprüfen kann? Vielen Dank
Rasto
2
Drücken Sie in Chrome F12, um Ihre Entwicklertools zu öffnen, und wechseln Sie dann zur Registerkarte Netzwerk. Wenn Ihre Anwendung eine HTTP-Anfrage sendet, wird diese in der Liste angezeigt, und Sie können darauf klicken, um die Header / den Text der Anfrage und der Antwort anzuzeigen. Weitere Informationen finden Sie in den Dokumenten. Wenn Sie gerade erst mit der Webentwicklung beginnen, können Sie lernen, wie Sie die Entwicklungstools Ihres Browsers verwenden :)
Joe Clay
1
@ JoeClay Die Antwort lautet also nein, der Browser sendet X-My-Custom-Headerweder noch Authorization. Die verbleibenden Fragen sind nun warum? Und wie kann man das beheben?
Rasto

Antworten:

109

Die Richtlinie mit demselben Ursprung beschränkt die Arten von Anforderungen, die eine Webseite an Ressourcen eines anderen Ursprungs senden kann.

Im no-cors Modus kann der Browser nur "einfache" Anforderungen senden - nur solche mit sicher gelisteten Methoden und sicher gelisteten Headern .

Um eine originensübergreifende Anfrage mit Headern wie Authorizationund zu senden X-My-Custom-Header, müssen Sie den no-corsModus löschen und Preflight-Anfragen unterstützen ( OPTIONS).

Die Unterscheidung zwischen „einfachen“ und „nicht einfachen“ Anfragen erfolgt aus historischen Gründen. Webseiten konnten immer einige Cross-Origin-Anfragen auf verschiedene Weise ausführen (z. B. durch Erstellen und Senden eines Formulars). Als Webbrowser ein prinzipielles Mittel zum Senden von Cross-Origin-Anfragen einführten ( Cross-Origin Resource Sharing oder CORS), war dies der Fall entschieden, dass solche „einfachen“ Anfragen von der Preflight- OPTIONSPrüfung ausgenommen werden könnten .

Vasiliy Faronov
quelle
3
Tolle Antwort, danke. Allerdings nicht die Antwort, die mich glücklich machen würde. Ich versuche jetzt, Unterstützung für CORS hinzuzufügen.
Rasto
@sideshowbarker ja, definitiv. Es ist. Nur CORS gut zu unterstützen, scheint nicht sehr einfach zu sein
Rasto
1
@sideshowbarker Schauen Sie sich mein Profil, sein Alter, Abzeichen und ältere Fragen an. Daraus sollten Sie verstehen, dass ich weiß, was ich gefragt habe und wie ich Aswer als akzeptiert markieren kann. Danke. Wenn Sie anderen wirklich raten möchten, was mit Antworten und Kopfgeldern zu tun ist, können Sie dies auf Meta tun. Diese Antwort wird möglicherweise erst dann als akzeptiert markiert, wenn CORS auf dem Server unterstützt wird. Ohne das habe ich keinen Beweis dafür, dass dies wirklich funktioniert (und 500 sind eine Menge Wiederholungen, die für falsche Antworten ausgegeben werden müssen). Wie Sie wissen sollten, bin ich auch nicht verpflichtet, es als akzeptiert zu markieren, auch wenn es funktioniert, da ich möglicherweise auf weitere / bessere Antworten warte.
Rasto
Das oben Gesagte wird gesagt, um Missverständnisse zu vermeiden: Ich mag Vasiliys Antwort für ihre hohe Qualität sehr und werde sie höchstwahrscheinlich akzeptieren, wenn sie funktioniert, sobald ich die CORS-Unterstützung für das Back-End (Firebase-Funktionen) erhalten kann.
Rasto
1
stackoverflow.com/questions/42755131/… Dies könnte helfen.
CaptainHere
24

Erstens : Verwenden Sie ein Objekt anstelle von new Headers(..):

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

Zweitens : Gut zu wissen, Header werden von fetch!!

Drittens : no-corsmode beschränkt die Verwendung von Headern auf diese weiße Liste:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Typeund dessen Wert ist ( application/x-www-form-urlencoded, multipart/form-data, text/plain)

Deshalb wird nur Ihr Content-TypeHeader gesendet und nicht X-My-Custom-Headeroder Authorization.

Damien
quelle
1

Ich hatte auch das gleiche Problem. Ich habe es behoben, indem ich 'no-cors' aus Javascript entfernt und im serverseitigen Spring Boot Folgendes hinzugefügt habe.

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

        }
    }
Greeshma
quelle
Fehlt hier ein Code? Wie kann der Methodenkörper mit '.' Beginnen? Soll das sein HttpSecurity.?
GreenAsJade
0

1. Wenn Sie Header in Ihrer exports.createCompany-Funktion aufrufen, haben Sie let headers = ['Headers: ']ein Großbuchstaben Hanstelle von Kleinbuchstaben, hwas zu Fehlern führen kann. Sie haben auch ein Komma nach dem Token in den Kopfzeilen, das nicht vorhanden sein sollte.

2. Jedes Mal, wenn ich Fetch-Anfragen in React Native verwendet habe, header:braucht das nicht new Headersdarauf.

Versuche dies:

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
})
Timmehlkk
quelle
Ein Hinweis zum nachfolgenden Komma, es wird zum Standard, ist ES2017, aber die Leute verwenden es mit Babel ( babeljs.io/docs/plugins/syntax-trailing-function-commas ) und auch NodeJS unterstützt es seit der Version 6.4.0. Dies sollte sich nicht auf das OP auswirken, da ich fetch()zuvor mit Erfolg nachgestellte Kommas verwendet habe .
Sgnl
Diese Antwort behandelt weder die erste noch die zweite Frage. Es gibt nur einige Syntaxkorrekturen.
Pungggi