wake-up-neo.net

CORS Pre-Flight kommt mit Access-Control-Allow-Origin zurück: *, Browser schlägt immer noch fehl

Durch das Auslösen einer AJAX GET zu http://qualifiedlocalhost:8888/resource.json wird der erwartete CORS-Pre-Flight ausgelöst.

OPTIONS-Anfrage vor dem Flug

Request URL:http://qualifiedlocalhost:8888/resource.json
Request Method:OPTIONS
Status Code:200 OK

Header anfordern

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, Origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:qualifiedlocalhost:8888
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36

Antwortheader

Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:2
Content-Type:text/plain
Date:Thu, 01 Aug 2013 19:57:43 GMT
Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly
X-Powered-By:Express

Gut aussehen?

Also sollte es funktionieren, richtig?

Die nachfolgende Anforderung schlägt jedoch mit dem Fehler XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin. fehl

Wahre Anfrage

Request URL:http://qualifiedlocalhost:8888/resource.json

Header anfordern

Accept:application/json, text/plain, */*
Cache-Control:no-cache
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
X-Requested-With:XMLHttpRequest

Hilfe!

Vielleicht starrt es direkt vor mir. Aber irgendwelche Ideen? Für den Fall, dass es relevant ist ... Ich verwende einen AngularJS $resource und spreche mit einem CompoundJS-Server.

19
tnunamak

Ändern Sie Ihre Access-Control-Allow-Methoden: 'GET, POST' in 'GET, POST, PUT, DELETE'

vor:

   app.use(function(req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
        res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
        next();
    });

Nach dem:

app.use(function(req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
    next();
});
13
KARTHIKEYAN.A

Ich hatte kürzlich das gleiche Problem . Das Problem ist, dass der Access-Control-Allow-Origin-Header (und, falls Sie ihn verwenden, der Access-Control-Allow-Credentials-Header) in both der Preflight-Antwort und der tatsächlichen Antwort gesendet werden muss.

Dein Beispiel hat es nur in der Preflight-Antwort.

Beinhaltet Ihr Webserver/Get-Funktion auch den HTTP-Header: Access-Control-Allow-Origin? Ich fand schließlich mit dieser Ergänzung Erfolg, indem ich AngularJS 1.0.7 und ein Remote-Java-Servlet verwendete. Hier ist mein Java-Code-Snippet - im AngularJS-Client waren keine Änderungen erforderlich:

Servlet:

@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Send Response
    super.doOptions(request,  response);
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /* ... */
    response.setHeader("Access-Control-Allow-Origin", "*");
}

Eine elegantere Alternative ist ein Servlet-Filter.

5
Jeff Collier

Wir haben das gleiche Problem festgestellt, bei dem der Server die richtigen CORS-Header sendet, der Browser jedoch nicht funktioniert, da er der Meinung ist, dass die CORS-Anforderungen nicht erfüllt werden. Interessanterweise geschieht dies in unserem Fall nur bei einigen AJAX - Aufrufen in derselben Browsersitzung, jedoch nicht bei allen.

Arbeitstheorie ...

Das Löschen des Browser-Cache löst das Problem in unserem Fall - Meine derzeitige Arbeitstheorie besagt, dass dies etwas mit Cookies zu tun hat, die vom Cross-Origin-Server gesetzt werden. Ich habe in Ihrem Szenario festgestellt, dass in der Antwort auf die OPTIONS-Anforderung vor dem Flug ein Cookie gesetzt wurde. Haben Sie versucht, dass der Server keine Cookies für Anforderungen anderer Herkunft setzt?

Wir haben jedoch festgestellt, dass das Problem in einigen Fällen nach dem Zurücksetzen des Browsers erneut auftrat. Wenn Sie den Browser im privaten Modus ausführen, wird das Problem behoben und auf Probleme mit dem Inhalt des Browser-Cache hingewiesen.

Hier ist mein Szenario (ich hätte fast eine neue Frage in SO gepostet, aber stattdessen hier):

Wir hatten einen Fehler, bei dem einige CORS GET-Anforderungen über jQuery.ajax fehlgeschlagen sind. In einer bestimmten Browsersitzung sehen wir die OPTIONS-Anforderung vor dem Flug durch, gefolgt von der tatsächlichen Anforderung. In derselben Sitzung gehen einige Anforderungen durch und andere schlagen fehl. 

Die Reihenfolge der Anforderungen und Antworten in der Browser-Netzwerkkonsole sieht wie folgt aus:

Zuerst die OPTIONS-Anfrage vor dem Flug

OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com 
Connection: keep-alive 
Access-Control-Request-Method: GET 
Origin: http://10.10.8.84:3003 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, Origin, x-csrf-token, auth 
Accept: */* Referer: http://10.10.8.84:3003/ 
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8

Was bekommt eine Antwort wie

HTTP/1.1 200 OK 
Date: Tue, 06 Aug 2013 19:18:22 GMT 
Server: Apache/2.2.22 (Ubuntu) 
Access-Control-Allow-Origin: http://10.10.8.84:3003 
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT 
Access-Control-Max-Age: 1728000 
Access-Control-Allow-Credentials: true 
Access-Control-Allow-Headers: accept, Origin, x-csrf-token, auth 
X-UA-Compatible: IE=Edge,chrome=1 
Cache-Control: no-cache 
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c 
X-Runtime: 0.001344 
X-Rack-Cache: invalidate, pass 
X-Powered-By: Phusion 
Passenger 4.0.2 
Status: 200 OK 
Vary: Accept-Encoding
Content-Encoding: gzip

Dann die eigentliche GET-Anfrage,

GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1 
Accept: application/json, text/javascript, */*; q=0.01 
Referer: http://10.10.8.84:3003/ 
Origin: http://10.10.8.84:3003 
X-CSRF-Token: xxxxxxx 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 
auth: xxxxxxxxx

Was in der Browser-Konsole einen Fehler anzeigt,

XMLHttpRequest
  cannot load https://api.obfuscatedserver.com/api/v1/users/337.
  Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.

Zusätzliches Debugging

Ich kann dieselbe Sequenz per curl wiedergeben und sehe gültige Antworten vom Server. Das heißt, sie haben die erwarteten CORS-Header, die die Anforderungen durchlaufen lassen sollten.

Wenn Sie dasselbe Szenario in einem nicht-privaten/inkognito-Browserfenster ausführen, wurde das Problem nicht reproduziert. Dies veranlasste mich zu versuchen, den Cache zu löschen, und das Problem wurde dadurch ebenfalls behoben. Aber nach einer Weile kam es zurück.

Das Problem war die Wiedergabe auf iPhone-Safari sowie auf Chrome auf dem OSX-Desktop.

Was brauche ich wirklich bei

Ich vermute, dass in der Cross-Origin-Domäne einige Cookies gesetzt sind, die sich hier engagieren und möglicherweise einen Fehler im Browser aufdecken. Gibt es Werkzeuge oder Haltepunkte, die ich im Browser einstellen kann (nativer Stack?), Um dies weiter zu testen und zu debuggen? Ein Haltepunkt im Code, der die CORS-Richtlinie bewertet, wäre ideal.

3

verwenden Sie das cors-Modul, um das Problem zu vermeiden

var cors = require('cors')

var app = express()
app.use(cors())
0
KARTHIKEYAN.A

Anscheinend funktioniert Ihre Antwort auf "Optionen" gut. Das Problem scheint in der Antwort "Get" zu sein.

Sie möchten, dass Ihre Antwort "get" die gleichen CORS-Header zurückgibt wie die Antwort "options". 

Insbesondere sollte die Antwort "Get" enthalten sein

Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
0
Larry Kang