CORS - Wie kann ein httprequest vorgeflogen werden?

94

Ich versuche, eine domänenübergreifende HTTP-Anfrage an den WCF-Dienst (den ich besitze) zu senden. Ich habe verschiedene Techniken zum Arbeiten mit den Einschränkungen für domänenübergreifende Skripte gelesen. Da mein Dienst sowohl GET- als auch POST-Anforderungen berücksichtigen muss, kann ich kein dynamisches Skript-Tag implementieren, dessen src die URL einer GET-Anforderung ist. Da ich Änderungen am Server vornehmen kann, habe ich begonnen, eine Problemumgehung zu implementieren, bei der die Serverantworten so konfiguriert werden, dass sie den Header "Access-Control-Allow-Origin" und Preflight-Anforderungen mit und OPTIONS-Anforderungen enthalten. Ich habe die Idee aus diesem Beitrag: CORS zum Laufen bringen

Auf der Serverseite fügt meine Webmethode der HTTP-Antwort 'Access-Control-Allow-Origin: *' hinzu. Ich kann sehen, dass die Antworten jetzt diesen Header enthalten. Meine Frage lautet: Wie 'preflight' ich eine Anfrage (OPTIONEN)? Ich verwende jQuery.getJSON, um die GET-Anfrage zu stellen, aber der Browser storniert die Anfrage sofort mit dem berüchtigten:

Origin http: // localhost ist von Access-Control-Allow-Origin nicht zulässig

Ist jemand mit dieser CORS-Technik vertraut? Welche Änderungen müssen beim Kunden vorgenommen werden, um meine Anfrage vorab zu bearbeiten?

Vielen Dank!

Nick
quelle

Antworten:

158

Während der Preflight-Anforderung sollten die folgenden zwei Header angezeigt werden: Access-Control-Request-Method und Access-Control-Request-Header. Diese Anforderungsheader fragen den Server nach Berechtigungen, um die eigentliche Anforderung zu stellen. Ihre Preflight-Antwort muss diese Header bestätigen, damit die eigentliche Anforderung funktioniert.

Angenommen, der Browser stellt eine Anfrage mit den folgenden Headern:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

Ihr Server sollte dann mit den folgenden Headern antworten:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

Achten Sie besonders auf den Antwortheader Access-Control-Allow-Headers. Der Wert dieses Headers sollte mit den Headern im Anforderungsheader für Zugriffssteuerungsanforderungsheader identisch sein und darf nicht '*' sein.

Sobald Sie diese Antwort an die Preflight-Anfrage senden, stellt der Browser die eigentliche Anfrage. Weitere Informationen zu CORS finden Sie hier: http://www.html5rocks.com/en/tutorials/cors/

Monsur
quelle
Können Sie Access-Control-Allow-Origin mehrere Domänen hinzufügen?
Botbot
@botbot Sie haben das wahrscheinlich schon herausgefunden, aber falls andere sich fragen, können Sie das tunAccess-Control-Allow-Origin: *
Steve Chambers
2
Ich habe möglicherweise etwas verpasst. Soll ich also zwei XMLHttp-Anfragen senden? Eine für den Preflight; Überprüfen Sie die Antwort auf Erfolg und senden Sie dann die eigentliche Anfrage?
Kangkan
14
@ Kangkan Sie müssen sich keine Sorgen um das Senden der Preflight-Anfrage machen. Wenn die Anfrage einen Preflight benötigt, sendet der Browser diese für Sie.
Monsur
4
DANKE für das "besondere Aufmerksamkeit" -Bit ... das mein Problem mit Node / Expressjs gelöst hat. Ich konnte einen Filter hinzufügen, um diese Preflight-Anfragen //cors and preflight filtering app.all('*', function(req, res, next){.. //preflight needs to return exact request-header res.set('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); if ('OPTIONS' == req.method) return res.send(204);next(); });
abzufangen
0

Obwohl dieser Thread aus dem Jahr 2014 stammt, kann das Problem für viele von uns immer noch aktuell sein. So habe ich in einem jQuery 1.12 / PHP 5.6-Kontext damit umgegangen:

  • jQuery hat seine XHR-Anforderung nur mit begrenzten Headern gesendet. Es wurde nur 'Origin' gesendet.
  • Es war keine Preflight-Anfrage erforderlich.
  • Der Server musste nur eine solche Anfrage erkennen und das "Access-Control-Allow-Origin:" hinzufügen. $ _SERVER ['HTTP_ORIGIN'] -Header, nachdem festgestellt wurde, dass es sich um eine XHR mit Kreuzursprung handelt.

PHP-Codebeispiel:

if (!empty($_SERVER['HTTP_ORIGIN'])) {
    // Uh oh, this XHR comes from outer space...
    // Use this opportunity to filter out referers that shouldn't be allowed to see this request
    if (!preg_match('@\.partner\.domain\.net$@'))
        die("End of the road if you're not my business partner.");

    // otherwise oblige
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
    // local request, no need to send a specific header for CORS
}

Fügen Sie insbesondere kein hinzu, exit;da kein Preflight erforderlich ist.

Fabien Haddadi
quelle