616 Stimmen

Wie sende ich eine Cross-Domain-POST-Anfrage über JavaScript?

Wie sende ich via JavaScript eine POST-Anfrage über verschiedene Domains hinweg?

Hinweise - die Seite sollte nicht neu geladen werden und ich muss die Antwort danach abrufen und analysieren.

0 Stimmen

Ich würde gerne ein wenig über den Anwendungsfall erfahren, der es Ihnen ermöglicht, dies zu versuchen. Könnten Sie bitte etwas darüber erzählen?

0 Stimmen

Grundsätzlich arbeite ich an einem Skript, das Text aus einer HTML-Datei an einen anderen Server zur Verarbeitung senden muss.

3 Stimmen

Kannst du einen Proxy einrichten, der dies auf der Serverseite ausführt und deinem Skript nur das Ergebnis liefert? Oder muss es zu 100% JavaScript sein?

406voto

rynop Punkte 45118

Aktualisierung: Bevor Sie fortfahren, sollte jeder das web.dev-Tutorial zu CORS lesen und verstehen. Es ist einfach zu verstehen und sehr klar.

Wenn Sie den Server steuern können, der POSTed wird, nutzen Sie einfach den "Cross-Origin Resource Sharing-Standard", indem Sie Antwortheader auf dem Server setzen. Diese Antwort wird in anderen Antworten in diesem Thread diskutiert, aber meiner Meinung nach nicht sehr deutlich.

Kurz gesagt, so erreichen Sie den Cross-Domain POST von from.com/1.html nach to.com/postHere.php (als Beispiel mit PHP). Hinweis: Sie müssen nur Access-Control-Allow-Origin für NICHTE OPTIONS-Anfragen festlegen - dieses Beispiel setzt immer alle Header für ein kleineres Code-Snippet.

  1. Richten Sie in postHere.php folgendes ein:

    switch ($_SERVER['HTTP_ORIGIN']) {
        case 'http://from.com': case 'https://from.com':
        header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
        break;
    }

    Dies ermöglicht es Ihrem Skript, Cross-Domain POST, GET und OPTIONS zu machen. Das wird Ihnen klar, wenn Sie weiterlesen...

  2. Richten Sie Ihren Cross-Domain POST von JS ein (Beispiel mit jQuery):

    $.ajax({ type: 'POST', url: 'https://to.com/postHere.php', crossDomain: true, data: '{"some":"json"}', dataType: 'json', success: function(responseData, textStatus, jqXHR) { var value = responseData.someKey; }, error: function (responseData, textStatus, errorThrown) { alert('POST fehlgeschlagen.'); } });

Wenn Sie den POST in Schritt 2 ausführen, sendet Ihr Browser eine "OPTIONS"-Methode an den Server. Das ist ein "Schnüffeln" des Browsers, um zu sehen, ob der Server damit einverstanden ist, dass Sie einen POST darauf machen. Der Server antwortet mit einem "Access-Control-Allow-Origin", das dem Browser sagt, dass es OK ist zu POST|GET|ORIGIN, wenn die Anfrage von "http://from.com" oder "https://from.com" stammt. Da der Server damit einverstanden ist, macht der Browser eine zweite Anfrage (diesmal ein POST). Es ist eine gute Praxis, dass Ihr Client den Inhaltstyp festlegt, den er sendet - daher müssen Sie auch das zulassen.

MDN hat einen großartigen Beitrag über HTTP-Zugriffskontrolle, der detailliert zeigt, wie der gesamte Ablauf funktioniert. Laut ihren Dokumenten sollte es "in Browsern funktionieren, die Cross-Site-XMLHttpRequest unterstützen". Das ist jedoch etwas irreführend, da ich denke, dass nur moderne Browser Cross-Domain POST erlauben. Ich habe nur verifiziert, dass dies mit Safari, Chrome, FF 3.6 funktioniert.

Beachten Sie Folgendes, wenn Sie dies tun:

  1. Ihr Server muss 2 Anfragen pro Operation verarbeiten
  2. Sie müssen über die Sicherheitsimplikationen nachdenken. Seien Sie vorsichtig, bevor Sie etwas wie 'Access-Control-Allow-Origin: *' tun
  3. Dies funktioniert nicht in mobilen Browsern. Meiner Erfahrung nach erlauben sie überhaupt keinen Cross-Domain-POST. Ich habe Android, iPad, iPhone getestet
  4. In FF < 3.6 gibt es einen ziemlich großen Fehler, bei dem, wenn der Server einen Nicht-400-Antwortcode zurückgibt UND es einen Antworttext gibt (zum Beispiel Validierungsfehler), FF 3.6 den Antworttext nicht erhält. Das ist ein großes Ärgernis, da Sie keine guten REST-Praktiken anwenden können. Siehe Fehler hier (es ist unter jQuery eingereicht, aber meine Vermutung ist, dass es ein FF-Fehler ist - scheint in FF4 behoben zu sein).
  5. Immer die obigen Header zurückgeben, nicht nur bei OPTIONS-Anfragen. FF benötigt sie in der Antwort vom POST.

125voto

Dan Fabulich Punkte 34037

Wenn Sie den Remote-Server kontrollieren, sollten Sie wahrscheinlich CORS verwenden, wie in dieser Antwort beschrieben; es wird in IE8 und höher sowie in allen aktuellen Versionen von FF, GC und Safari unterstützt. (Aber in IE8 und 9 wird CORS nicht erlauben, Cookies im Request zu senden.)

Also, wenn Sie den Remote-Server nicht kontrollieren oder wenn Sie IE7 unterstützen müssen oder wenn Sie Cookies benötigen und IE8/9 unterstützen müssen, möchten Sie wahrscheinlich eine Iframe-Technik verwenden.

  1. Erstellen Sie ein Iframe mit einem eindeutigen Namen. (Iframes verwenden einen globalen Namensraum für den gesamten Browser, wählen Sie also einen Namen, den keine andere Website verwenden wird.)
  2. Erstellen Sie ein Formular mit versteckten Eingaben, das auf das Iframe abzielt.
  3. Senden Sie das Formular ab.

Hier ist Beispielcode; Ich habe es auf IE6, IE7, IE8, IE9, FF4, GC11, S5 getestet.

function crossDomainPost() {
  // Füge das Iframe mit einem eindeutigen Namen hinzu
  var iframe = document.createElement("iframe");
  var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
  document.body.appendChild(iframe);
  iframe.style.display = "none";
  iframe.contentWindow.name = uniqueString;

  // Erstellen Sie ein Formular mit versteckten Eingaben, das auf das Iframe abzielt
  var form = document.createElement("form");
  form.target = uniqueString;
  form.action = "http://INSERT_YOUR_URL_HERE";
  form.method = "POST";

  // Wiederholen Sie dies für jeden Parameter
  var input = document.createElement("input");
  input.type = "hidden";
  input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
  input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
  form.appendChild(input);

  document.body.appendChild(form);
  form.submit();
}

Vorsicht! Sie können die Antwort des POST nicht direkt lesen, da das Iframe auf einer separaten Domain existiert. Frames dürfen nicht miteinander kommunizieren von unterschiedlichen Domains; dies ist die Same-Origin-Policy.

Wenn Sie den Remote-Server kontrollieren, aber CORS nicht verwenden können (z.B. weil Sie in IE8/IE9 sind und Cookies verwenden müssen), gibt es Möglichkeiten, das gleiche Herkunftspolitik zu umgehen, zum Beispiel durch die Verwendung von window.postMessage und/oder eine Reihe von Bibliotheken, die es Ihnen ermöglichen, in älteren Browsern plattformübergreifende plattformübergreifende Nachrichten zu senden:

Wenn Sie den Remote-Server nicht kontrollieren, können Sie die Antwort des POST nicht lesen, Punkt. Andernfalls würde es Sicherheitsprobleme verursachen.

50voto

Lou Franco Punkte 85315
  1. Erstellen Sie ein iFrame,
  2. fügen Sie ein Formular mit versteckten Eingaben ein,
  3. setzen Sie die Aktion des Formulars auf die URL,
  4. Fügen Sie das iFrame dem Dokument hinzu
  5. senden Sie das Formular ab

Pseudocode

 var ifr = document.createElement('iframe');
 var frm = document.createElement('form');
 frm.setAttribute("action", "deineurl");
 frm.setAttribute("method", "post");

 // versteckte Eingaben erstellen, hinzufügen
 // nicht gezeigt, aber ähnlich (erstellen, setAttribute, appendChild)

 ifr.appendChild(frm);
 document.body.appendChild(ifr);
 frm.submit();

Sie möchten wahrscheinlich das iFrame stylen, um es zu verstecken und absolut zu positionieren. Es ist nicht sicher, ob der Browser Cross-Site-Posting zulässt, aber wenn ja, so geht es.

25voto

Alain Gauthier Punkte 730

Einfach halten:

  1. cross-domain POST:
    Verwenden Sie crossDomain: true,

  2. Sollte die Seite nicht aktualisieren:
    Nein, die Seite wird nicht aktualisiert, da der success oder error asynchrone Rückruf aufgerufen wird, wenn der Server die Antwort zurücksendet.


Beispiel Skript:

$.ajax({
        type: "POST",
        url: "http://www.yoururl.com/",
        crossDomain: true,
        data: 'param1=value1¶m2=value2',
        success: function (data) {
            // etwas mit den Daten der Serverantwort machen
        },
        error: function (err) {
            // Fehlerlogik hier behandeln
        }
    });

16voto

Robb Lovell Punkte 177

Wenn Sie Zugriff auf alle beteiligten Server haben, fügen Sie das Folgende in den Header der Antwort für die angeforderte Seite in der anderen Domäne ein:

PHP:

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

Zum Beispiel, im Drupal-Code von xmlrpc.php würden Sie dies tun:

function xmlrpc_server_output($xml) {
    $xml = ''."\n". $xml;
    header('Connection: close');
    header('Content-Length: '. strlen($xml));
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/x-www-form-urlencoded');
    header('Date: '. date('r'));
    // $xml = str_replace("\n", " ", $xml); 

    echo $xml;
    exit;
}

Dies führt wahrscheinlich zu einem Sicherheitsproblem, und Sie sollten sicherstellen, dass Sie die geeigneten Maßnahmen ergreifen, um die Anfrage zu überprüfen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X