it-swarm.com.de

Warum wird eine OPTIONS-Anfrage gesendet und kann ich sie deaktivieren?

Ich baue eine Web-API. Ich habe festgestellt, dass ich immer, wenn ich Chrome zum POST verwende, auf meine API zugreifen, immer eine OPTIONS-Anforderung vor der eigentlichen Anforderung gesendet wird, was ziemlich ärgerlich ist. Momentan bekomme ich den Server, um alle OPTIONS-Anfragen zu ignorieren. Jetzt ist meine Frage, was ist gut, um eine OPTIONS-Anfrage zu senden, um die Serverlast zu verdoppeln? Gibt es eine Möglichkeit, den Browser vollständig vom Senden von OPTIONS-Anforderungen abzuhalten? 

271
Elgs Qian Chen

edit 2018-09-13: Einige Präzisierungen bezüglich dieser Anforderung vor dem Flug und wie sie am Ende dieser Antwort vermieden werden können.

OPTIONS-Anforderungen nennen wir pre-flight-Anforderungen in Cross-Origin resource sharing (CORS).

Sie sind erforderlich, wenn Sie in bestimmten Situationen Anfragen aus verschiedenen Bereichen ableiten. 

Diese Anforderung vor dem Flug wird von einigen Browsern als Sicherheitsmaßnahme durchgeführt, um sicherzustellen, dass die durchgeführte Anforderung vom Server als vertrauenswürdig eingestuft wird. Dies bedeutet, dass der Server versteht, dass die Methode, Origin und Header, die in der Anfrage gesendet werden, sicher gehandhabt werden können. 

Ihr Server sollte diese Anforderungen nicht ignorieren, sondern behandeln, wenn Sie versuchen, Origin-Anforderungen zu bearbeiten.

Eine gute Ressource finden Sie hier http://enable-cors.org/

Um dies zu erreichen, können Sie sicherstellen, dass der Server für jeden Pfad mit der Methode OPTIONS eine Antwort mit diesem Header sendet 

Access-Control-Allow-Origin: *

Dadurch wird dem Browser mitgeteilt, dass der Server Anfragen von einem beliebigen Origin beantworten möchte. 

Weitere Informationen zum Hinzufügen von CORS-Unterstützung zu Ihrem Server finden Sie im folgenden Flussdiagramm

http://www.html5rocks.com/static/images/cors_server_flowchart.png

CORS Flowchart


edit 2018-09-13

Die CORS OPTIONS-Anforderung wird nur in einigen Fällen ausgelöst, wie in MDN docs erläutert:

Einige Anfragen lösen keinen CORS-Preflight aus. Diese werden in diesem Artikel als "einfache Anforderungen" bezeichnet, obwohl die Abrufspezifikation (die CORS definiert) diesen Begriff nicht verwendet. Eine Anfrage, die kein CORS-Preflight auslöst - eine sogenannte "einfache Anfrage" - erfüllt alle folgenden Bedingungen:

Die einzigen zulässigen Methoden sind:

  • GET
  • HEAD
  • POST

Abgesehen von den vom Benutzeragenten automatisch festgelegten Kopfzeilen (z. B. Connection, User-Agent oder einem der anderen Kopfzeilen, deren Namen in der Abrufspezifikation als "verbotener Kopfnamenname" definiert sind), dürfen nur die Kopfzeilen verwendet werden manuell gesetzt sind diejenigen, die von der Fetch-Spezifikation als "CORS-safelisted request-header" definiert werden.

  • Akzeptieren
  • Accept-Language
  • Inhaltssprache
  • Inhaltstyp (bitte beachten Sie die zusätzlichen Anforderungen unten)
  • DPR
  • Downlink
  • Daten speichern
  • Viewport-Breite
  • Breite

Die einzigen zulässigen Werte für den Content-Type-Header sind:

  • application/x-www-form-urlencoded
  • multipart/Formulardaten
  • text/plain

Es sind keine Ereignis-Listener für jedes in der Anforderung verwendete XMLHttpRequestUpload-Objekt registriert. Auf diese wird mit der Eigenschaft XMLHttpRequest.upload zugegriffen.

In der Anforderung wird kein ReadableStream-Objekt verwendet.

256
Leo Correa

Ich habe dieses Problem durchgegangen, ist unten meine Schlussfolgerung zu diesem Problem und meine Lösung.

Gemäß der Strategie von CORS (Ich empfehle Ihnen dringend, darüber zu lesen) Sie können den Browser nicht einfach dazu zwingen, das Senden der OPTION-Anfrage zu beenden, wenn er dies für nötig hält. 

Es gibt zwei Möglichkeiten, um dies zu umgehen

    1. Stellen Sie sicher, dass Ihre Anfrage eine "einfache Anfrage" ist.
    1. Legen Sie Access-Control-Max-Age für die Anforderung OPTION fest

Einfache Anfrage

Eine einfache standortübergreifende Anforderung erfüllt alle folgenden Bedingungen:

Die einzigen zulässigen Methoden sind:

  • GET
  • HEAD
  • POST

Abgesehen von den automatisch vom Benutzeragenten eingestellten Kopfzeilen (z. B. Connection, User-Agent usw.) sind folgende Kopfzeilen die einzigen, die manuell gesetzt werden dürfen:

  • Akzeptieren
  • Accept-Language
  • Inhaltssprache
  • Inhaltstyp

Die einzigen zulässigen Werte für den Content-Type-Header sind:

  • application/x-www-form-urlencoded
  • multipart/Formulardaten
  • text/plain

Eine einfache Anfrage führt nicht zu einer OPTION-Anfrage vor dem Flug.

Legen Sie einen Cache für die OPTION-Prüfung fest

Sie können einen Access-Control-Max-Age für die Anforderung OPTION festlegen, damit die Berechtigung erst nach Ablauf der Gültigkeitsdauer erneut geprüft wird.

Access-Control-Max-Age gibt den Wert in Sekunden an, für den die Antwort auf die Preflight-Anforderung zwischengespeichert werden kann, ohne eine weitere Preflight-Anforderung zu senden.

133
Neekey

Bitte beziehen Sie sich auf diese Antwort auf den tatsächlichen Bedarf an OPTIONS-Anfragen vor dem Flug: CORS - Was ist die Motivation für die Einführung von Preflight-Anfragen?

Um die Anforderung OPTIONS zu deaktivieren, müssen die folgenden Bedingungen für eine Ajax-Anforderung erfüllt sein:

  1. Request setzt keine benutzerdefinierten HTTP-Header wie "application/xml" oder "application/json" usw
  2. Die Anforderungsmethode muss eine der Methoden GET, HEAD oder POST sein. Bei POST sollte der Inhaltstyp application/x-www-form-urlencoded, multipart/form-data oder text/plain sein.

Referenz: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

132
device_exec

Wenn die Debug-Konsole geöffnet ist und die Option Disable Cache aktiviert ist, werden Preflight-Anforderungen immer gesendet (d. H. Vor jeder einzelnen Anforderung). Wenn Sie den Cache nicht deaktivieren, wird eine Anforderung vor dem Flug nur einmal gesendet (pro Server).

40
Nir

Ja, es ist möglich, Optionsanfragen zu vermeiden. Optionsanforderung ist eine Preflight-Anforderung, wenn Sie Daten an eine andere Domäne senden (senden). Es handelt sich um ein Sicherheitsproblem des Browsers. Wir können jedoch eine andere Technologie verwenden: iframe-Transportschicht. Ich empfehle Ihnen dringend, alle CORS-Konfigurationen zu vergessen und die Readymade-Lösung zu verwenden. 

Schauen Sie hier nach: https://github.com/jpillora/xdomain

Und Arbeitsbeispiel: http://jpillora.com/xdomain/

Einen schönen Tag noch!

38
user889349

Wie bereits in früheren Beiträgen erwähnt, gibt es OPTIONS-Anfragen aus einem bestimmten Grund. Bei Problemen mit langen Antwortzeiten von Ihrem Server (z. B. Verbindung in Übersee) können Sie auch die Preflight-Anforderungen in Ihrem Browser zwischenspeichern.

Lassen Sie Ihren Server mit dem Access-Control-Max-Age-Header antworten, und für Anforderungen, die an denselben Endpunkt gehen, wurde die Preflight-Anforderung zwischengespeichert und tritt nicht mehr auf.

14
enpenax

Ein Entwickler, der den Grund kennt, aus dem er existiert, aber auf eine API zugreifen muss, die keine OPTIONS-Aufrufe ohne Auth ausführt, brauche eine temporäre Antwort, sodass ich mich lokal entwickeln kann, bis der API-Besitzer die richtige SPA CORS-Unterstützung hinzufügt oder eine Proxy-API erhält in Betrieb. 

Ich habe festgestellt, dass Sie CORS in Safari und Chrome auf einem Mac deaktivieren können.

Dieselbe Origin-Richtlinie in Chrome deaktivieren

Chrome: Beenden Sie Chrome, öffnen Sie ein Terminal und fügen Sie folgenden Befehl ein: open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir

Safari: Deaktivieren der Same-Origin-Richtlinie in Safari

Wenn Sie die Same-Origin-Richtlinie in Safari deaktivieren möchten (ich habe 9.1.1), müssen Sie nur das Entwicklermenü aktivieren und im Entwicklungsmenü die Option "Cross-Origin-Beschränkungen deaktivieren" auswählen.

12
Joseph Juhnke

Ich habe dieses Problem gerne gelöst.

if($_SERVER['REQUEST_METHOD'] == 'OPTIONS' && ENV == 'devel') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: X-Requested-With');
    header("HTTP/1.1 200 OK");
    die();
}

Es ist nur für die Entwicklung. Damit warte ich 9ms und 500ms und nicht 8s und 500ms. Ich kann das tun, weil die JS-App für die Produktion auf derselben Maschine wie die Produktion ist. Es wird also keine OPTIONS geben, aber die Entwicklung ist meine lokale.

6
AntiCZ

Sie können nicht, aber Sie könnten vermeiden, dass CORS JSONP verwendet.

5
Jose Mato

Nachdem ich anderthalb Tage damit verbracht hatte, ein ähnliches Problem durchzuarbeiten, fand ich es mitISIS

Mein Web-API-Projekt wurde wie folgt eingerichtet:

// WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
    var cors = new EnableCorsAttribute("*", "*", "*");
    config.EnableCors(cors);
    //...
}

Ich hatte keine CORS-spezifischen Konfigurationsoptionen in dem web.config> system.webServer-Knoten, wie ich ihn in so vielen Beiträgen gesehen habe

Kein CORS-spezifischer Code in der global.asax oder in der Steuerung als Dekorateur

Das Problem war die App Pool Einstellungen

Der verwaltete Pipeline-Modus wurde auf klassisch gesetzt (hat ihn in integriertes geändert) und der Identity wurde auf Netzwerkdienst gesetzt (hat sich in ApplicationPoolIdentity geändert)

Das Ändern dieser Einstellungen (und das Aktualisieren des App-Pools) hat es für mich behoben.

0
Ju66ernaut