Tödliches CORS, wenn http: // localhost der Ursprung ist

183

Ich bin mit diesem CORS-Problem festgefahren, obwohl ich den Server (nginx / node.js) mit den entsprechenden Headern festgelegt habe.

Ich kann im Chrome-Netzwerkbereich sehen -> Antwortheader:

Access-Control-Allow-Origin:http://localhost

was sollte den Trick tun.

Hier ist der Code, den ich jetzt zum Testen verwende:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

Ich bekomme

XMLHttpRequest kann http://stackoverflow.com/ nicht laden . Origin http: // localhost ist von Access-Control-Allow-Origin nicht zulässig.

Ich vermute, es ist ein Problem im Client-Skript und nicht in der Serverkonfiguration ...

Whadar
quelle
44
Nein, stackoverflow.com muss diesen Header festlegen, nicht Sie. : x. Was wäre der Punkt der gleichen Herkunftspolitik sonst.
Esailija
3
Versuchen Sie, auf den Server zuzugreifen, den Sie eingerichtet haben, ohne Stapelüberlauf. ;)
Nek
DOH! Gibt es eine Möglichkeit, Chrome (oder einem anderen Browser) mitzuteilen, dass die Ressource abgerufen werden soll, auch wenn der Header fehlt, wenn mein Ursprung localhost ist?
Whadar
Führen Sie Ihre Codes in Chrome (20.0.1132.57, Windows 7) aus, funktioniert einwandfrei.
Imwilsonxu
1
Wenn Sie localhost mit einem Port verwenden, hat diese Antwort für mich unter serverfault.com/a/673551/238261 funktioniert .
Nelu

Antworten:

228

Chrome unterstützt localhost nicht für CORS-Anfragen (ein Fehler, der 2010 mit WontFix 2014 markiert wurde).

Um dies zu umgehen, können Sie eine Domain wie lvh.me(die genau wie localhost auf 127.0.0.1 zeigt) verwenden oder Chrome mit dem --disable-web-securityFlag starten (vorausgesetzt, Sie testen nur).

Beau
quelle
24
@greensuisse - es wird nicht auf localhost gepostet. Das Problem ist das Posten von localhost.
Cheeso
9
Dieser Fehler ist ungültig (und wurde als solcher markiert - crbug.com/67743#c17 ). Esailijas Kommentar ist korrekt. Wenn Sie diese Header zu localhost hinzufügen, erhalten Sie nicht auf magische Weise Zugriff auf alle anderen Websites. Es ist der Remote-Standort, der mit diesen Headern bedient werden muss.
Rob W
22
Ich habe gerade 2 Stunden mit Chrome getestet, um festzustellen, dass es in Firefox einwandfrei funktioniert.Grrrr...
FloatingRock
11
Andere Option: Bearbeiten Sie Ihre Hosts-Datei so, dass local. [Mysite] .com auf 127.0.0.1 zeigt, und lassen Sie dann Ihre CORS-Datei *. [Mysite] .com
Tom
6
Ich hatte das gleiche Problem mit FireFox. Ich konnte es nur auf Edge schaffen! Netter Beitrag, fantastisch! :)
Luis Gouveia
53

Laut der Antwort von @ Beau unterstützt Chrome keine CORS-Anforderungen von localhost, und es ist unwahrscheinlich, dass sich diese Richtung ändert.

Ich verwende die Allow-Control-Allow-Origin: * Chrome-Erweiterung , um dieses Problem zu umgehen. Die Erweiterung fügt die erforderlichen HTTP-Header für CORS hinzu:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

Der Quellcode wird auf Github veröffentlicht .

Beachten Sie, dass die Erweiterung standardmäßig alle URLs filtert. Dies kann einige Websites beschädigen (zum Beispiel: Dropbox). Ich habe es geändert, um nur lokale Host- URLs mit dem folgenden URL-Filter zu filtern

*://localhost:*/*
Hanxue
quelle
14
Wenn Sie das Problem lesen, auf das @beau verweist, werden Sie feststellen, dass Chrome 100% Ursprungsübergreifende Anforderungen an und von localhost unterstützt. Die Ausgabe wurde 2014 geschlossen, da sie nicht reproduziert werden konnte. Der Rest des Rauschens in diesem Thread sind Personen mit falsch konfigurierten Servern ohne Ursprung (wie bei der ursprünglichen Frage hier).
Molomby
1
Arbeitete wie ein Zauber für mich auf Chrom
Aakash Sahai
3
Diese Erweiterung funktioniert nicht, Access-Control-Allow-Credentials: trueda sie Access-Control-Allow-Originauf *beide eingestellt ist und diese hat trueund *von Browsern blockiert wird. Wenn Sie die Anmeldeinformationen true verwenden, müssen Sie den Ursprung ohne Platzhalter verwenden. Ich empfehle Moesif Origins und CORS Changer Extension, mit denen Sie die Header nach Belieben ändern können.
Samuel
Vielleicht mache ich etwas falsch, aber diese Erweiterung scheint für mich nicht mehr zu funktionieren.
James Parker
19

Das eigentliche Problem ist, dass Chrome die -Allow-Anforderung abbricht, wenn wir sie für alle Anforderungen ( OPTIONS& POST) festlegen . Der folgende Code funktioniert für mich mit POSTLocalHost mit Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>
Greensuisse
quelle
15
OP verwendet nginx / node.js. Nicht PHP
code_monk
4

Chrome wird Anfragen mit CORS von einem localhostUrsprung ganz gut machen. Dies ist kein Problem mit Chrome.

Der Grund, warum Sie nicht laden können, http://stackoverflow.comist, dass die Access-Control-Allow-OriginHeader Ihren localhostUrsprung nicht zulassen .

Brad
quelle
2

Schnelle und schmutzige Korrektur der Chrome-Erweiterung:

Moesif Orign & CORS Wechsler

Chrome unterstützt jedoch originensübergreifende Anforderungen von localhost. Achten Sie darauf , einen Header für hinzufügen Access-Control-Allow-Originzu localhost.

kaleazy
quelle
Ich habe diese Erweiterung zu meiner Opera hinzugefügt und jetzt ist sie fertig. Ich kann nie sagen, wann es ein- und ausgeschaltet ist, also benutze ich Firefox für die Arbeit. und Oper für die Entwicklung. Google Suit mag es nicht und andere Dinge auch nicht.
Maddocks
0

Keine der Erweiterungen funktionierte für mich, daher habe ich einen einfachen lokalen Proxy installiert. In meinem Fall https://www.npmjs.com/package/local-cors-proxy Es handelt sich um eine 2-minütige Einrichtung:

(von ihrer Seite)

npm install -g local-cors-proxy

API-Endpunkt, den wir anfordern möchten und der CORS-Probleme aufweist: https://www.yourdomain.ie/movies/list

Proxy starten: lcp --proxyUrl https://www.yourdomain.ie

Dann in Ihrem Client-Code neuer API-Endpunkt: http://localhost:8010/proxy/movies/list

Hat für mich wie ein Zauber funktioniert: Ihre App ruft den Proxy an, der den Server anruft. Keine CORS-Probleme.

daniel p
quelle
0

Ich habe mich entschieden, keine Header zu berühren und stattdessen eine Weiterleitung auf der Serverseite vorzunehmen, und es woks wie ein Zauber.

Das folgende Beispiel bezieht sich auf die aktuelle Version von Angular (derzeit 9) und wahrscheinlich auf jedes andere Framework, das Webpacks DevServer verwendet. Aber ich denke, dass das gleiche Prinzip auch für andere Backends gilt.

Daher verwende ich die folgende Konfiguration in der Datei proxy.conf.json :

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

Im Falle von Angular diene ich mit dieser Konfiguration:

$ ng serve -o --proxy-config=proxy.conf.json

Ich bevorzuge die Verwendung des Proxys im Befehl serve, aber Sie können diese Konfiguration auch wie folgt in angular.json einfügen :

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

Siehe auch:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

Juri Sinitson
quelle