it-swarm.com.de

Domainübergreifend AJAX Anfrage funktioniert nicht

Ich rufe POST für eine Drittanbieter-API auf, mit der ich über die $ .ajax-Funktion von jQuery gearbeitet habe. Wenn ich den Anruf tätige, erhalte ich jedoch die folgende Fehlermeldung: XMLHttpRequest cannot load http://the-url.com. The request was redirected to 'http://the-url.com/anotherlocation', which is disallowed for cross-Origin requests that require preflight. 

Ich habe aus diesem Beitrag gesehen, dass dies ein Webkit-Fehler sein könnte, also habe ich es in Firefox versucht (ich entwickle in Chrome) und habe das gleiche Ergebnis erhalten. Ich habe dies auf Chrome und Firefox versucht und bekomme es das gleiche Ergebnis. 

Per this post habe ich auch versucht, jsonp zu verwenden, indem ich die crossDomain -Eigenschaft der $ .ajax-Funktion auf true und die dataType auf jsonp gesetzt habe. Dies führte jedoch zu einem internen Serverfehler von 500.

Wenn ich Chrome mit dem Flag "--disable-web-security" starte, habe ich keine Probleme. Wenn ich jedoch den Browser normal starte, erhalte ich die Fehlermeldung.

Ich denke, das könnte eine zweiteilige Frage sein. Was kann ich für diese domänenübergreifende Anfrage tun? Wenn JSONP die Antwort ist, wie kann ich dann herausfinden, ob die Drittanbieter-API richtig eingerichtet ist, um dies zu unterstützen?

EDIT: Hier ist der Screenshot, wenn ich den Anruf mit deaktivierter Browsersicherheit tätige: https://drive.google.com/file/d/0Bzo7loNBQcmjUjk5YWNWLXM2SVE/edit?usp=sharing

Hier ist der Screenchost, wenn ich den Anruf mit aktivierter Browsersicherheit tätige (wie normal): https://drive.google.com/file/d/0Bzo7loNBQcmjam5NQ3BKWUluRE0/edit?usp=sharing

13
Don

Die Lösung, die ich entwickelte, war die Verwendung von cURL (wie von @waki erwähnt), aber eine leicht modifizierte Version, die SOAP unterstützt. Anstelle des Aufrufs von AJAX an die Drittanbieter-API (die falsch konfiguriert ist), rufe ich meine lokale PHP -Datei auf, die dann einen SOAP -Aufruf an die Drittanbieter-API durchführt und gibt die Daten an meine PHP - Datei zurück, wo ich sie dann verarbeiten kann. Dadurch kann ich CORS und alle damit verbundenen Komplexitäten vergessen. Hier ist der Code (genommen und geändert aus this question, aber ohne Authentifizierung).

$post_data = "Some xml here";
$soapUrl = "http://yoursite.com/soap.asmx"; // asmx URL of WSDL


$headers = array(
    "Content-type: text/xml;charset=\"utf-8\"",
    "Accept: text/xml",
    "Cache-Control: no-cache",
    "Pragma: no-cache",
    "SOAPAction: http://yoursite.com/SOAPAction",
    "Content-length: " . strlen($post_data),
); //SOAPAction: your op URL

$url = $soapUrl;

// PHP cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // the SOAP request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);

/* Check for an error when processing the request. */
if(curl_errno($ch) != 0) {
   // TODO handle the error
}

curl_close($ch);

// TODO Parse and process the $response variable (returned as XML)
3
Don

Zu Ihrer ersten Frage

Was kann ich tun, um diese domänenübergreifende Anfrage zu stellen?

Die folgenden Anforderungsheader werden zuerst an den Server gesendet. Basierend auf den Antwort-Headern verwirft der UserAgent, d. H. Der Browser hier, die Antwort (falls vorhanden) und gibt sie nicht an den XHR-Rückruf zurück, wenn die Header nicht addiert werden.

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, OPTIONS Access-Control-Allow-Headers: X-Custom-Header

Beispiel aus - https://stackoverflow.com/a/8689332/1304559

Sie können Tools wie Fiddler oder den Web Inspector-Tab "Netzwerk" (Chrome) oder den Firebug-Tab "Netzwerk" verwenden, um die Header zu ermitteln, die der Server als Antwort auf Ihre Anfrage zurücksendet.

Die API-Server-URL des Drittanbieters sollte mit den unterstützten Werten antworten. Wenn nicht, ist das dein Problem.

Kann bei JsonP 500-Serverfehlern nicht viel helfen, da dort Internal Server Error steht


[~ # ~] Update [~ # ~]

Ich habe Ihre Screenshots gesehen, ein paar Dinge, die Sie hier bemerken sollten

  1. HTTP POST Wird verwendet
  2. In der Antwort beider Modi wurden keine Access-Control - Header gefunden. Mit zweitem Statuscode als 302
  3. Der Anforderungsheader von Origin ist null, daher glaube ich, dass die HTML-Datei nicht von einer Website, sondern vom Dateisystem aus geöffnet wird

JSONP aktivieren

An den Punkt gebracht, warum JSONP nicht funktioniert, Grund: Die Webdienstkonfiguration (von ASMX angegeben) hat den GET -Modus für die Anforderung nicht aktiviert. JSONP funktioniert nicht mit POST.

Warum 200 Mit deaktivierter Sicherheit?

Die POST Anfrage wird direkt aufgerufen, ohne dass zuvor eine OPTIONS oder Preflight-Anfrage ausgelöst wurde, sodass der Server einfach antwortet.

Warum 302 - Statuscode mit aktivierter Sicherheit?

Zunächst ein wenig darüber, wie es passiert, wenn das Sicherheitsflag nicht deaktiviert ist (Standardeinstellung). Die OPTIONS -Anforderung wird an die URL gesendet. Die URL sollte mit einer Liste von HTTP-Methoden antworten, die verwendet werden können, z. B. GET, POST usw. Der Statuscode dieser OPTIONS -Anforderung sollte 200.

Im aktuellen Fall wird dabei eine Umleitung aufgerufen. Die Umleitung verweist auf einen benutzerdefinierten Fehlerbehandler für einen HTTP-Serverfehler. Ich glaube, es ist ein 404 - Fehler, der abgefangen und umgeleitet wird. [Dies könnte daran liegen, dass der benutzerdefinierte Handler auf ResponseRedirect anstelle von ResponseRewrite eingestellt ist.] Der Grund für die 404 Ist der domänenübergreifende Zugriff nicht aktiviert.

Wenn die benutzerdefinierte Fehlerbehandlung deaktiviert wurde, hätte dies den Code HTTP 500 Zurückgegeben. Ich glaube, dass das Problem gefunden werden kann, indem die Serverprotokolle sofort nach dem Auslösen einer domänenübergreifenden Anforderung überprüft werden. Es empfiehlt sich, die Serverprotokolle auf andere Fehler als diese zu überprüfen.

Mögliche Lösung

Um den Zugriff zu ermöglichen, gibt es zwei Möglichkeiten - hier beschrieben . Oder fügen Sie die Zugriffssteuerungs-Header direkt dem Abschnitt customheaders der Datei web.config Hinzu.

Wenn der domänenübergreifende Zugriff aktiviert ist, sollte der Server auf OPTIONEN antworten und zulassen, dass die Anforderung durchlaufen wird. Dies sollte HTTP 200 Zurückgeben, sofern keine anderen Fehler vorliegen. Ajax Callback kann jedoch nicht auf die Antwort zugreifen. Dies ist jetzt nur möglich, wenn Access-Control-Allow-Origin Auf "*" oder den Anforderungsheaderwert Origin und bei Bedarf auf Access-Control Gesetzt ist. Und der Ajax-Rückruf erhält die Antwort wie vorgesehen.

Der dritte Punkt ist null Origin. Dies ist problematisch, wenn der Anforderungsheaderwert Origin als Access-Control-Allow-Origin Zurückgesendet wird. Ich gehe jedoch davon aus, dass Sie Ihre HTML-Seite auf einen Webserver verschieben, sodass dies kein Problem darstellen sollte.

Hoffe das hilft!

20
aravind

Sie können cURL? Verwenden. Mit Ajax senden Sie Daten an Ihren Handler (auf Ihrem Server heißt callback.php) . In Ihrer Datei (callback.php) verwenden Sie cURL mit Ihren Daten:

$post_data = array( 
    'key' => 'key', 
    'test' => 'text'
    ); 

$curl = curl_init(); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($curl, CURLOPT_POST, TRUE); 
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);  
curl_setopt($curl, CURLOPT_URL, 'http://www.domain.com/'); 
$return = json_decode(trim(curl_exec($curl)), TRUE); 
curl_close($curl); 

in Ihrer $ return-Variable erhalten Sie Ihre Daten.

1
waki