2010-08-02 14 views
7

Alles funktioniert perfekt in Firefox und Chrome, aber außer in IE8 (8.0.6001.18702)IE8 XSS/JQuery Problem

Dies ist der Testcode (JQuery 1.4.2) (gleiches Problem mit $ .post):

$(function() { 
    $.get("http://domain2.tld/some.php", {}, function(response) { 
     alert(response); 
    }); 
}); 

Dieser Code in domain1.tld ausgeführt wird, und es wird von domain2.tld geladen, auf diese Weise:

<script type="text/javascript" src="http://domain2.tld/test.js"></script> 

ich eine bekommen "Zugriff verweigert" -Meldung in IE8. Ich habe bisher ohne Erfolg versucht:

1) Zugabe in domain1.tld (PHP-Code):

header("X-XSS-Protection: 0"); 

2) Deaktivieren von XSS-Filter in IE8 Optionen.

Ich bin mit IE8 Debugger und es zeigt den Fehler in Zeile 5113:

xhr.open(type, s.url, s.async); 

Wenn statt $ .get des Aufrufs (domain2.tld ...), ich nenne $ .get (domain1. tld ...) Es gibt keinen Fehler, der mir bestätigt, dass es sich um ein XSS-Problem "gleicher Herkunft" handelt.

Meine einzige Lösung (denke ich) ist es durch einen Proxy (PHP-Code), aber ich würde es vorziehen, es nicht zu tun, da es die Leistung beeinflusst.

Haben Sie eine Alternative zu diesem Problem?

Hinweis: Das Aktualisieren von IE8 ist keine Option, da ich es ohne Updates testen möchte.

Ein sehr ähnliches Problem Mine: http://forum.jquery.com/topic/jquery-ui-tabs-ie8-and-injecting-elements-into-dom

Antwort

5

(Ich empfehle die Liste, die ich vor dieser Antwort schreiben zu überprüfen)

den Prozess zu erleichtern, nahm ich die CORS-Plugin und es modifizierte. Sie müssen Ihren vorhandenen Jquery-Code nicht ändern, wenn Sie nur $ .get und $ .post verwenden. Ich habe es in IE8 getestet und es funktioniert wie erwartet. Für den Rest der Browser werden die normalen JQuery-Aufrufe verwendet. Sie können diesen Code sogar bei Bedarf hinzufügen (mit bedingten Tags). Lesen Sie die ersten Kommentare für weitere Informationen. Ich hoffe, es hilft ...

Hier ist der Code (es zum Beispiel als jquery.xdomain.js speichern):

/* 
* XDR (non-XHR) extension functions for IE8+ 
* Based in CORS plugin (http://plugins.jquery.com/project/cors) 
* Modified by A.Lepe (www.alepe.com, Aug 2010) 
* 
* It supports calls using $.get and $.post only. 
* The main difference between the CORS plugin and this one are: 
* 
* 1) This method tries first to use XDR and if not available 
* will try to use XHR. This is to prevent any alert or 
* security message from IE. 
* 
* 2) To minimize size and target only IE8+ versions, this method 
* does not provides an alternative fall-back. 
* CORS version uses proxy_xmlhttp.js as fall-back option (see link #1 below). 
* 
* If you want to support "OLD" browsers, an alternative fall-back 
* can be easily implemented (instead the error alert). 
* For example, something like: 
* 
* ... 
* } catch(e) { 
* data["proxy_url"] = url; 
* $._get(proxy, data, callback, type); 
* } 
* ... 
* 
* in which "proxy" must be a URL where your proxy is located. 
* Your proxy may look like: 
* 
* <?php 
    //GET method example: 
    $URL = $_GET["proxy_url"]; 
    unset($_GET["proxy_url"]); 
    $params = http_build_query($_GET); 
    echo file_get_contents($URL."?".$params)); 
* ?> 
* 
* For POST method you may check link #2. 
* 
* NOTES: 
* 
* $.post() method it might not work as expected. XDR does 
* not send the data to the server in the same way XHR do 
* (am I missing something?). In order to have access to that 
* POST data you will need to: 
* 
* a) set: 
*  always_populate_raw_post_data = On 
*  register_long_arrays = On 
* 
* OR : 
* 
* b) import it manually (see link #3): 
    //-------- Import XDR POST data --------- 
    if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) { 
     $data = explode('&', $GLOBALS["HTTP_RAW_POST_DATA"]); 
     foreach ($data as $val) { 
      if (!empty($val)) { 
       list($key, $value) = explode('=', $val); 
       $_POST[$key] = urldecode($value); 
      } 
     } 
    } 
* 
* Remember to add the respective headers in the server that will 
* allow the XDR calls: 
     header('Access-Control-Allow-Origin: *'); //Or http://example.com 
     header('Access-Control-Max-Age: 3628800'); 
     header('Access-Control-Allow-Methods: GET, POST'); 
*/ 
(function($) { 
$._get = $.get; 
$._post = $.post; 
$.get = function (url, data, callback, type) { 
    // try XDR 
    if (jQuery.browser.msie && window.XDomainRequest) { 
     var params = ''; 
     for (var key in data) { 
      params += ((params || url.indexOf("?") != -1)?'&':'?')+key+'='+data[key]; 
     } 
     // Use Microsoft XDR 
     var xdr = new XDomainRequest(); 
     xdr.open("GET", url+params); 
     xdr.onload = function() { 
      callback(this.responseText, 'success'); 
     }; 
     xdr.send(); 
    } else { 
     try { 
      // Try using jQuery to get data 
      $._get(url, data, callback, type); 
     } catch(e) { 
      alert(e.message); 
     } 
    } 
} 
$.post = function (url, data, callback, type) { 
    // Try XDR 
    if (jQuery.browser.msie && window.XDomainRequest) { 
     var params = ''; 
     for (var key in data) { 
      params += (params?'&':'')+key+'='+data[key]; 
     } 
     // Use XDR 
     var xdr = new XDomainRequest(); 
     xdr.open("POST", url); 
     xdr.send(params); 
     xdr.onload = function() { 
      callback(xdr.responseText, 'success'); 
     }; 
    } else { 
     try { 
      // Try using jQuery to POST 
      $._post(url, data, callback, type); 
     } catch(e) { 
      alert(e.message); 
     } 
    } 
} 
})(jQuery); 

Links:

+0

Vielen Dank dafür! Als ich dies jedoch kürzlich für einen Randfall verwendete, entdeckte ich, dass es leicht die native Funktionalität von '$ .get' und' $ .post' unterbricht, die jeweils ein jqXHR-Objekt zurückgeben. Dies lässt sich leicht beheben, indem Sie die try-Blöcke in Ihrem Code so anpassen, dass 'return $ ._ get (URL, Daten, Callback, Typ);' und 'return $ ._ post (URL, Daten, Callback, Typ);' – itsmequinn

-1

Ich werde haben mit JANDY hier, es ist sehr unwahrscheinlich, dass Sie es überhaupt arbeiten bekamen zustimmen. Es gilt die gleiche Ursprungsrichtlinie (http://en.wikipedia.org/wiki/Same_origin_policy). Am besten schreiben Sie einen lokalen Proxy, den Ihr Skript abfragt, und lassen den Proxy dann die domänenübergreifenden Aufrufe durchführen.

8

Es tut mir leid, wenn mein Englisch nicht perfekt ist, wie ich sehen kann, war ich nicht klar genug ... Einer meiner wichtigsten Anliegen wird von anderen Person erklärt hier: http://http://forum.jquery.com/topic/cross-domain-ajax-and-ie

Also, welche Alternative gibt es?

1) XDomainRequest

Ich persönlich denke, dies ist der beste Weg Cross-Site Scripting in IE8 + zu implementieren (wie es nativ unterstützt wird). Das einzige Problem ist, dass es nur einen Microsoft-Weg gibt. Aber so viele andere Dinge mit IE-Familie können wir JQuery Ajax-Funktionalität leicht erweitern.

Gemäß der Dokumentation müssen Sie einige zusätzliche Header in Domäne1 angeben.tld, for example, in PHP wie folgt aus:

header("Access-Control-Allow-Origin: http://domain2.tld"); //use * for any 

Vielleicht ist die nächste Alternative ist nützlich, um die jquery Implementierung von XDomainRequest zur Verfügung zu stellen;

Update (a): Es gibt einen XDR library (nicht jquery), die "Ersetzen" die XHR Klasse es Cross-Browser zu machen, ist es Sitz in pmxdr client library. Ich habe es noch nicht versucht.

2) CORS

Das einzige Problem mit diesem Plugin ist, dass ist nicht gerade eine Erweiterung der Funktionen noch anders benannt werden, so müssen Sie entweder Ihre Codes ändern oder dieses Plugin wickeln.

Update (b): Ich habe das CORS-Plugin geändert, um es einfacher zu machen. Überprüfen Sie meine andere Antwort, um den Code zu erhalten.

3) JsonP in JQuery

Dies sollte der einfachste Weg, um mein Problem zu lösen (wie ich die Kontrolle über beide Server haben). Nativ unterstützen die meisten Browser Cross-Site-Scripting, nur wenn das JSON-Format verwendet wird (ich glaube, dass auch XML verwendet werden kann). In diesem Fall wird die Funktion $ .getJSON() verwendet. Damit es funktioniert, müssen Sie (wie die Dokumentationszustände) Callback =? in der URL, zum Beispiel:

$.getJSON("http://domain2.tld/index.php?callback=?",funciton(res){ ... }); 

Die "?" nach „Rückruf“ wird mit einer Kennung ... in Ihrer PHP-Datei ersetzt wird, müssen Sie diese Kennung erhalten und den Json Code wie folgt umgeben:

print_r($_GET["callback"])."(".json_encode($mydata).");"; 

(ich das Beispiel von here bekam)

Das Problem mit dieser Methode ist, dass, wenn Sie nur HTML abrufen möchten, muss es innerhalb eines JSON-Objekts befinden und damit den Prozess ein wenig komplizierter und überwältigend machen.

4) jquery.jsonp plugin

Wenn Sie zusätzliche Validierungen und Funktionen der nativen JSONP Unterstützung in JQuery benötigen, dann versuchen Sie dieses Plugin, das auch den Prozess vereinfachen.

5) xdomainajax

Dieses Plugin verwendet eine interessante aproach mit Yahoos Dienst YQL, in denen jede Web-Seite (oder ein Teil davon) auf Json umgewandelt werden, wodurch es möglich, sie in Javascript zu importieren. Diese Methode eignet sich für Situationen, in denen Sie das Ursprungsformat nicht ändern können.

6) flXHR

Diese Lösung nutzt Flash (swf), um die Magie zu erreichen. Ich könnte sagen, dass dies eine sehr schnelle Möglichkeit ist, um eine nahezu browserübergreifende Implementierung zu erreichen (da Flash-Unterstützung erforderlich ist). Diese Methode ist möglicherweise ideal für die Sites, in denen Flash (sicher) vorhanden sein wird. Wenn Ihre Website jedoch keinen Flash-Speicher benötigt, wird dies zum Hauptnachteil, da Benutzer Flash installiert haben sollten, damit dies funktioniert.

7) xdajax

Diese Lösung wird in YUI Implementierung zusammen mit dem "Flash" Ansatz.

8) Wenn keine der vorherigen Optionen gut für Sie ist, denken Sie daran, dass Sie immer noch den alten Trick des Einfügens eines Tags zum Importieren von JS-Code verwenden können.

9) Die Verringerung der IE-Sicherheit auf das Minimum löst auch das Problem. Aber ich denke, es wird nicht gut sein, eine Nachricht wie folgt zu haben: "Bitte senken Sie Ihre Sicherheitseinstellungen, um diese Seite zu benutzen" ... lol

Ich hoffe, dass dies anderen in einer ähnlichen Situation helfen kann.

+0

Ausgezeichneter Bericht. –