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 FlugRequest 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
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
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
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.
Ä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();
});
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.
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.
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.
verwenden Sie das cors-Modul, um das Problem zu vermeiden
var cors = require('cors')
var app = express()
app.use(cors())
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:*