wake-up-neo.net

Warum erhalte ich eine OPTIONS-Anfrage anstelle einer GET-Anfrage?

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script>
$.get("http://example.com/", function(data) {
     alert(data);
});
</script>

es stellt eine OPTIONS-Anfrage an diese URL, und dann wird der Rückruf niemals mit irgendetwas aufgerufen. 

Wenn es nicht domänenübergreifend ist, funktioniert es gut.

Sollte jQuery nicht einfach den Aufruf mit einem <script>-Knoten machen und dann den Callback ausführen, wenn es geladen ist? Ich verstehe, dass ich das Ergebnis nicht erhalten kann (da es domänenübergreifend ist), aber das ist in Ordnung. Ich möchte nur, dass der Anruf durchgeht. Ist das ein Fehler oder mache ich etwas falsch?

246
Paul Tarjan
85
Paul Tarjan

Nach MDN ,

Preflight-Anfragen

Im Gegensatz zu einfachen Anforderungen (oben erörtert) werden "Preflighted" -Anforderungen zuerst Senden Sie einen HTTP OPTIONS-Anforderungsheader an die Ressource auf der anderen Seite Domäne, um festzustellen, ob die tatsächliche Anforderung sicher ist senden. Anforderungen für standortübergreifende Anforderungen werden so geprüft, da sie Auswirkungen auf Benutzerdaten haben. Eine Anforderung ist insbesondere vorgeflogen, wenn:

  • Es verwendet andere Methoden als GET oder POST. Auch wenn POST zum Senden von .__ verwendet wird. Daten mit einem anderen Inhaltstyp als .__ anfordern. application/x-www-form-urlencoded, mehrteilig/Formulardaten oder text/plain, z.B. wenn die Anforderung POST mit .__ eine XML-Nutzlast an den Server sendet. application/xml oder text/xml, dann wird die Anforderung als Preflight ausgeführt. 
  • Es legt benutzerdefinierte Header in der Anfrage fest (beispielsweise verwendet die Anfrage einen Header wie X-PINGOTHER).
224
arturgrigor

Wenn Sie versuchen, _ _ zu posten,

Stellen Sie sicher, dass Sie Ihre Formulardaten JSON.stringify und als text/plain senden.

<form id="my-form" onSubmit="return postMyFormData();">
    <input type="text" name="name" placeholder="Your Name" required>
    <input type="email" name="email" placeholder="Your Email" required>
    <input type="submit" value="Submit My Form">
</form>

function postMyFormData() {

    var formData = $('#my-form').serializeArray();
    formData = formData.reduce(function(obj, item) {
        obj[item.name] = item.value;
        return obj;
    }, {});
    formData = JSON.stringify(formData);

    $.ajax({
        type: "POST",
        url: "https://website.com/path",
        data: formData,
        success: function() { ... },
        dataType: "text",
        contentType : "text/plain"
    });
}
4
Derek Soike

Ich glaube nicht, dass jQuery natürlich eine JSONP-Anfrage macht, wenn eine solche URL angegeben wird. Es wird jedoch eine JSONP-Anforderung ausgeführt, wenn Sie angeben, welches Argument für einen Rückruf verwendet werden soll:

$.get("http://metaward.com/import/http://metaward.com/u/ptarjan?jsoncallback=?", function(data) {
     alert(data);
});

Es ist Sache des empfangenden Skripts, dieses Argument zu verwenden (das nicht als "jsoncallback" bezeichnet werden muss). In diesem Fall wird die Funktion also nie aufgerufen. Da Sie jedoch angegeben haben, dass Sie das Skript auf metaward.com nur ausführen möchten, würde dies dazu führen.

2
VoteyDisciple

Ich hatte das gleiche Problem. Mein Fix bestand darin, meinem Skript PHP Header hinzuzufügen, die nur in dev-Umgebungen vorhanden sind.

Dies ermöglicht domänenübergreifende Anforderungen:

header("Access-Control-Allow-Origin: *");

Dadurch wird der Preflight-Anforderung mitgeteilt, dass der Client die gewünschten Header senden darf:

header("Access-Control-Allow-Headers: *");

Auf diese Weise muss die Anforderung nicht geändert werden.

Wenn sich in Ihrer Dev-Datenbank vertrauliche Daten befinden, die möglicherweise durchgesickert sind, sollten Sie dies zweimal überlegen.

1
fivebit

Ändern Sie einfach "application/json" in "text/plain" und vergessen Sie nicht die JSON.stringify (request):

var request = {Company: sapws.dbName, UserName: username, Password: userpass};
    console.log(request);
    $.ajax({
        type: "POST",
        url: this.wsUrl + "/Login",
        contentType: "text/plain",
        data: JSON.stringify(request),

        crossDomain: true,
    });
1
David Lopes

Tatsächlich sind domänenübergreifende AJAX - (XMLHttp) -Anfragen aus Sicherheitsgründen nicht zulässig (z. B. das Abrufen einer "eingeschränkten" Webseite von der Clientseite und das Zurücksenden an den Server. Dies wäre ein Sicherheitsrisiko ).

Die einzige Problemumgehung sind Rückrufe. Dies ist: Erstellen eines neuen Skriptobjekts und Verweisen der src auf das JavaScript auf der letzten Seite, bei dem es sich um einen Rückruf mit JSON-Werten (myFunction ({data})) handelt. MyFunction ist eine Funktion, die mit den Daten etwas tut (z. B. Speichern) in einer Variablen).

1
Adrián Navarro

In meinem Fall hatte das Problem nichts mit CORS zu tun, da ich jQuery POST auf demselben Webserver ausgab. Die Daten waren JSON, aber ich hatte den Parameter dataType: 'json' weggelassen. 

Ich hatte keinen contentType-Parameter, wie in der Antwort von David Lopes oben gezeigt.

0
GarDavis

Ich konnte es mit Hilfe der folgenden Header beheben

Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
Access-Control-Allow-Methods

Wenn Sie auf Nodejs sind, finden Sie hier den Code, den Sie kopieren/einfügen können.

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin','*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH');
  next();
});
0
obai

Es sieht so aus, als würden Firefox und Opera (auch auf Mac getestet) die gegenseitige Domäne nicht mögen (aber Safari ist damit einverstanden). 

Sie müssen möglicherweise einen lokalen Serverseitencode aufrufen, um die Remote-Seite zu aktivieren. 

0
helloandre