it-swarm.com.de

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

Wie sende ich eine domänenübergreifende POST -Anforderung über JavaScript?

Hinweise - Die Seite sollte nicht aktualisiert werden, und ich muss die Antwort danach packen und analysieren.

530
Ido Schacham

Update: Bevor Sie fortfahren, sollte jeder das html5rocks Tutorial auf CORS lesen und verstehen. Es ist leicht zu verstehen und sehr klar.

Wenn Sie steuern, dass der Server POST ist, nutzen Sie einfach den "Cross-Origin Resource Sharing-Standard", indem Sie Antwortheader auf dem Server festlegen. Diese Antwort wird in anderen Antworten in diesem Thread behandelt, meiner Meinung nach jedoch nicht sehr klar.

Kurz gesagt, wie Sie die Cross-Domain POST von from.com/1.html bis nach.com/postHere.php ausführen (mit PHP als Beispiel). Hinweis: Sie müssen nur Access-Control-Allow-Origin für NON OPTIONS-Anforderungen festlegen. In diesem Beispiel werden immer alle Header für ein kleineres Code-Snippet festgelegt.

  1. In postHere.php richten Sie 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;
    }
    

    Dadurch kann Ihr Skript domänenübergreifende POST, GET und OPTIONS erstellen. Dies wird klar, wenn Sie weiter lesen ...

  2. Richten Sie Ihre Cross Domain POST von JS ein (Beispiel für 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 failed.');
        }
    });
    

Wenn Sie in Schritt 2 den POST ausführen, sendet Ihr Browser eine "OPTIONS" -Methode an den Server. Dies ist ein "Schnüffel" des Browsers, um zu sehen, ob der Server cool ist, wenn Sie ihn posten. Der Server antwortet mit "Access-Control-Allow-Origin" und teilt dem Browser mit, dass er OK ist, um POST | GET | Origin zu starten, wenn die Anfrage von " http://from.com " oder " https: //" stammt. from.com ". Da der Server damit einverstanden ist, stellt der Browser eine zweite Anfrage (diesmal einen POST). Es ist empfehlenswert, dass Ihr Client den Inhaltstyp festlegt, den er sendet. Daher müssen Sie dies auch zulassen.

MDN hat eine großartige Beschreibung von HTTP-Zugriffskontrolle , in der detailliert beschrieben wird, wie der gesamte Ablauf funktioniert. Laut ihren Dokumenten sollte es "in Browsern funktionieren, die Site-XMLHttpRequest unterstützen". Dies ist jedoch ein wenig irreführend, da THINK nur moderne Browser den domänenübergreifenden POST erlauben. Ich habe das nur mit Safari, Chrome, FF 3.6, nachgewiesen.

Beachten Sie Folgendes, wenn Sie dies tun:

  1. Ihr Server muss 2 Anforderungen pro Vorgang bearbeiten
  2. Sie müssen über die Auswirkungen auf die Sicherheit nachdenken. Seien Sie vorsichtig, bevor Sie etwas wie 'Access-Control-Allow-Origin: *' tun. 
  3. Dies funktioniert nicht bei mobilen Browsern. Meiner Erfahrung nach erlauben sie überhaupt keine Cross Domain POST. Ich habe Android, iPad, iPhone getestet
  4. In FF <3.6 gibt es einen ziemlich großen Fehler. Wenn der Server einen Nicht-400-Antwortcode zurückgibt UND ein Antworttext vorliegt (z. B. Validierungsfehler), erhält FF 3.6 keinen Antworttext. Dies ist ein enormer Schmerz im Arsch, da Sie keine guten REST -Praktiken anwenden können. Siehe Bug hier (es wurde unter jQuery abgelegt, aber meine Vermutung ist ein FF-Fehler - scheint in FF4 behoben zu sein).
  5. Geben Sie immer die obigen Kopfzeilen zurück, nicht nur bei OPTION-Anforderungen. FF benötigt es in der Antwort vom POST.
369
rynop

Wenn Sie den Remote-Server steuern, Sie sollten 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. (In IE8 und 9 erlaubt CORS das Senden von Cookies in der Anfrage jedoch nicht.)

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

  1. Erstellen Sie einen Iframe mit einem eindeutigen Namen. (iframes verwenden einen globalen Namespace für den gesamten Browser. Wählen Sie daher einen Namen, den keine andere Website verwenden wird.)
  2. Konstruieren Sie ein Formular mit ausgeblendeten Eingaben, das auf den Iframe abzielt.
  3. Senden Sie das Formular.

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

_function crossDomainPost() {
  // Add the iframe with a unique name
  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;

  // construct a form with hidden inputs, targeting the iframe
  var form = document.createElement("form");
  form.target = uniqueString;
  form.action = "http://INSERT_YOUR_URL_HERE";
  form.method = "POST";

  // repeat for each 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();
}
_

In acht nehmen! Sie können die Antwort des POST nicht direkt lesen, da der iframe in einer separaten Domäne vorhanden ist. Frames dürfen nicht über verschiedene Domänen miteinander kommunizieren. Dies ist die Same-Origin-Richtlinie .

Wenn Sie den Remote-Server steuern, CORS jedoch nicht verwenden können (z. B. weil Sie sich in IE8/IE9 befinden und Cookies verwenden müssen), gibt es Möglichkeiten, um die gleiche Origin-Richtlinie zu umgehen, z. B. mithilfe von window.postMessage und/oder eine von mehreren Bibliotheken, mit denen Sie domänenübergreifende Cross-Frame-Nachrichten in älteren Browsern senden können:

Wenn Sie den Remote-Server nicht steuern, können Sie die Antwort des POST-Zeitraums nicht lesen. Andernfalls würden Sicherheitsprobleme verursacht.

119
Dan Fabulich
  1. Erstellen Sie einen iFrame, 
  2. ein Formular mit versteckten Eingaben einfügen, 
  3. setzen Sie die Aktion des Formulars auf die URL. 
  4. Hinzufügen von iframe zum Dokument
  5. senden Sie das Formular

Pseudocode

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

 // create hidden inputs, add them
 // not shown, but similar (create, setAttribute, appendChild)

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

Wahrscheinlich möchten Sie den iframe so gestalten, dass er versteckt und absolut positioniert ist. Es ist nicht sicher, ob das Cross-Site-Posten vom Browser zugelassen wird, aber wenn ja, gehen Sie folgendermaßen vor.

47
Lou Franco

Halte es einfach: 

  1. domänenübergreifender POST:
    benutze crossDomain: true,

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


Beispielskript:

$.ajax({
        type: "POST",
        url: "http://www.yoururl.com/",
        crossDomain: true,
        data: 'param1=value1&param2=value2',
        success: function (data) {
            // do something with server response data
        },
        error: function (err) {
            // handle your error logic here
        }
    });
21
Alain Gauthier

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

PHP:

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

Im Drupal-Code xmlrpc.php würden Sie beispielsweise Folgendes tun:

function xmlrpc_server_output($xml) {
    $xml = '<?xml version="1.0"?>'."\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 erforderlichen Maßnahmen ergreifen, um die Anforderung zu überprüfen.

16
Robb Lovell

Überprüfen Sie die Funktion post_method in http://taiyolab.com/mbtweet/scripts/twitterapi_call.js - ein gutes Beispiel für die oben beschriebene iframe-Methode.

9
ndeuma
  1. Erstellen Sie zwei versteckte Iframes (fügen Sie dem CSS-Stil "display: none;" hinzu). Lassen Sie Ihren zweiten iframe auf etwas in Ihrer eigenen Domain verweisen.

  2. Erstellen Sie ein ausgeblendetes Formular, setzen Sie die Methode auf "post" mit target = Ihrem ersten iframe und optional für enctype auf "multipart/form-data" (Ich denke, Sie möchten POST), weil Sie senden möchten mehrteilige Daten wie Bilder?)

  3. Wenn Sie fertig sind, senden Sie das Formular zum POST.

  4. Wenn Sie die andere Domain dazu bringen können, Javascript zurückzugeben, das die domänenübergreifende Kommunikation mit Iframes ermöglicht ( http://softwareas.com/cross-domain-communication-with-iframes ), dann haben Sie Glück und Sie kann auch die Antwort erfassen. 

Wenn Sie Ihren Server als Proxy verwenden möchten, können Sie dies natürlich ganz vermeiden. Senden Sie das Formular einfach an Ihren eigenen Server, der die Anfrage an den anderen Server weiterleitet (vorausgesetzt, der andere Server ist nicht so eingerichtet, dass er IP-Unstimmigkeiten bemerkt), erhält die Antwort und gibt zurück, was Sie möchten.

6
Magarshak

Eine weitere wichtige Sache, die beachtet werden muss !!! In example oben wird die Verwendung beschrieben 

$.ajax({
    type     : 'POST',
    dataType : 'json', 
    url      : 'another-remote-server',
    ...
});

JQuery 1.6 und niedriger hat einen Fehler mit domänenübergreifendem XHR . Laut Firebug wurden keine Anforderungen außer OPTIONS gesendet. Keine Post. Überhaupt.

Ich habe 5 Stunden lang meinen Code getestet/eingestellt. Viele Header auf dem Remote-Server hinzufügen (Skript). Ohne Wirkung ... Aber später habe ich JQuery lib auf 1.6.4 aktualisiert, und alles funktioniert wie ein Zauber.

6
BasTaller

Wenn Sie dies in einer ASP.net-MVC-Umgebung mit JQuery AJAX durchführen möchten, führen Sie die folgenden Schritte aus: (Dies ist eine Zusammenfassung der Lösung, die unter this thread angeboten wird). 

Angenommen, "caller.com" (kann eine beliebige Website sein) muss auf "server.com" (einer ASP.net-MVC-Anwendung) gepostet werden.

  1. Fügen Sie in der Web.config-Anwendung "server.com" den folgenden Abschnitt hinzu:

      <httpProtocol>
          <customHeaders>
              <add name="Access-Control-Allow-Origin" value="*" />
              <add name="Access-Control-Allow-Headers" value="Content-Type" />
              <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
          </customHeaders>
      </httpProtocol>
    
  2. Auf "server.com" haben wir die folgende Aktion auf dem Controller (genannt "Home"), zu der wir posten werden:

    [HttpPost]
    public JsonResult Save()
    {
        //Handle the post data...
    
        return Json(
            new
            {
                IsSuccess = true
            });
    }
    
  3. Stellen Sie dann von "caller.com" aus folgende Daten aus einem Formular (mit der HTML-ID "formId") auf "server.com":

    $.ajax({
            type: "POST",
            url: "http://www.server.com/home/save",
            dataType: 'json',
            crossDomain: true,
            data: $(formId).serialize(),
            success: function (jsonResult) {
               //do what ever with the reply
            },
            error: function (jqXHR, textStatus) {
                //handle error
            }
        });
    
5
Sujeewa

Ich denke, der beste Weg ist, XMLHttpRequest (z. B. $ .ajax (), $ .post () in jQuery) mit einem der Cross-Origin-Ressourcenfreigaben zu verwenden. Polyfills https://github.com/Modernizr/Modernizr/wiki/ HTML5-Cross-Browser-Polyfills # wiki-CORS

3
Roman Dolgiy

Dies ist eine alte Frage, aber eine neue Technologie könnte jemandem helfen.

Wenn Sie über Administratorzugriff auf den anderen Server verfügen, können Sie das Forge-Projekt OpenSource verwenden, um Ihren domänenübergreifenden POST durchzuführen. Forge bietet einen domänenübergreifenden JavaScript-XmlHttpRequest-Wrapper, der die Raw-Socket-API von Flash nutzt. Der POST kann sogar über TLS erfolgen.

Der Grund, aus dem Sie administrativen Zugriff auf den Server benötigen, für den Sie POST bereitstellen, besteht darin, dass Sie eine domänenübergreifende Richtlinie angeben müssen, die den Zugriff von Ihrer Domäne aus ermöglicht.

http://github.com/digitalbazaar/forge

3
dlongley

High level .... Sie müssen auf Ihrem Server einen Cnamen einrichten, damit other-serve.ihr-server.com auf other-server.com verweist.

Ihre Seite erstellt dynamisch einen unsichtbaren Iframe, der als Transport zu other-server.com dient. Sie müssen dann über JS von Ihrer Seite zu den anderen Servern kommunizieren und haben Rückrufe, die die Daten auf Ihre Seite zurückbringen. 

Möglich, erfordert jedoch eine Koordination von your-server.com und other-server.com

3
Dan

Es gibt einen weiteren Weg (mit HTML5-Funktion). Sie können einen Proxy-Iframe verwenden, der in dieser anderen Domäne gehostet wird. Sie senden eine Nachricht mit postMessage an diesen Iframe. Anschließend kann der iframe POST -Anforderung (in derselben Domäne) ausführen und postMessage mit reposnse an das übergeordnete Fenster zurückgeben.

elternteil auf sender.com

var win = $('iframe')[0].contentWindow

function get(event) {
    if (event.Origin === "http://reciver.com") {
        // event.data is response from POST
    }
}

if (window.addEventListener){
    addEventListener("message", get, false)
} else {
    attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");

iframe auf reciver.com

function listener(event) {
    if (event.Origin === "http://sender.com") {
        var data = JSON.parse(event.data);
        $.post(data.url, data.data, function(reponse) {
            window.parent.postMessage(reponse, "*");
        });
    }
}
// don't know if we can use jQuery here
if (window.addEventListener){
    addEventListener("message", listener, false)
} else {
    attachEvent("onmessage", listener)
}
3
jcubic

Sollte dies mit einer benutzerdefinierten YQL-Tabelle + JS XHR möglich sein, lesen Sie Folgendes: http://developer.yahoo.com/yql/guide/index.html

Ich benutze es, um einige clientseitige (js) html-Scraping zu machen, funktioniert einwandfrei (Ich habe einen vollständigen Audioplayer, mit Suche im Internet/Wiedergabelisten/Text/letzte FM-Informationen, alle Client-js + YQL)

1
Guillaume86

Ich weiß, das ist eine alte Frage, aber ich wollte meine Herangehensweise teilen. Ich benutze cURL als Proxy, sehr einfach und konsistent. Erstellen Sie eine PHP-Seite namens submit.php und fügen Sie den folgenden Code hinzu:

<?

function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}

$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));

Dann in Ihrer js (jQuery hier):

$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
    var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
    alert('POST failed.');
}
});
1
Ivan Durst

CORS ist für Sie . CORS ist "Cross Origin Resource Sharing", eine Möglichkeit, domänenübergreifende Anforderungen zu senden. Jetzt unterstützen XMLHttpRequest2 und Fetch API beide CORS und können sowohl POST als auch GET-Anforderung senden

Es hat jedoch seine Grenzen. Der Server muss den Access-Control-Allow-Origin spezifisch beanspruchen, und er kann nicht auf '*' gesetzt werden.

Und wenn Sie möchten, dass eine Origin-Anfrage an Sie gesendet werden kann, benötigen Sie JSONP (außerdem muss Access-Control-Allow-Origin gesetzt sein, kann jedoch '*' sein).

Für viele Anfragen, wenn Sie nicht wissen, wie Sie wählen sollen, benötigen Sie dafür eine vollständige Funktionskomponente. Lassen Sie mich eine einfache Komponente vorstellen: https://github.com/Joker-Jelly/catta


Wenn Sie einen modernen Browser verwenden (> IE9, Chrome, FF, Edge usw.), empfehlen Sie Very, eine einfache, aber schöne Komponente zu verwenden: https://github.com/Joker-Jelly/catta. Es hat keine Abhängigkeit (weniger als 3 KB) und unterstützt Fetch, AJAX und JSONP mit derselben tödlichen Beispielsyntax und Optionen.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

Es unterstützt auch den gesamten Weg in Ihr Projekt zu importieren, wie ES6-Modul, CommonJS und sogar <script> in HTML.

1
Jelly

Wenn Sie Zugriff auf den domänenübergreifenden Server haben und keine serverseitigen Codeänderungen vornehmen möchten, können Sie eine Bibliothek mit dem Namen "xdomain" verwenden. 

Wie es funktioniert: 

Schritt 1: Server 1: Fügen Sie die xdomain-Bibliothek hinzu und konfigurieren Sie die Cross-Domain als Slave:

<script src="js/xdomain.min.js" slave="https://crossdomain_server/proxy.html"></script>

Schritt 2: Erstellen Sie auf einem Cross-Domain-Server eine proxy.html-Datei und fügen Sie Server 1 als Master ein:

proxy.html:
<!DOCTYPE HTML>
<script src="js/xdomain.min.js"></script>
<script>
  xdomain.masters({
    "https://server1" : '*'
  });
</script>

Schritt 3:

Jetzt können Sie einen Aufruf von AJAX an proxy.html als Endpunkt von Server1 aus durchführen. Dies umgeht die CORS-Anforderung. Die Bibliothek verwendet intern eine iframe-Lösung, die mit Credentials und allen möglichen Methoden arbeitet: GET, POST usw.

Ajax-Code abfragen:

$.ajax({
        url: 'https://crossdomain_server/proxy.html',
        type: "POST",
        data: JSON.stringify(_data),
        dataType: "json",
        contentType: "application/json; charset=utf-8"
    })
    .done(_success)
    .fail(_failed)
0
Raj Malakpet