2010-08-02 91 views
7

一切都運行完美在Firefox和Chrome,但除了在IE8(8.0.6001.18702)IE8 XSS/jQuery的問題

這是測試代碼(jQuery的1.4.2)(同樣的問題。員額$):

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

這個代碼在執行domain1.tld並從domain2.tld加載,這樣說:

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

我得到一個IE8中的「權限被拒絕」的消息。到目前爲止我曾嘗試沒有成功:

1)在domain1.tld加入(PHP代碼):

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

2)在IE8選項禁用XSS濾波器。

我使用IE8的調試器,它體現在5113線的錯誤:

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

如果不是調用$獲得(domain2.tld ...),我調用$獲得(DOMAIN1。 tld ...)沒有錯誤,這證實了我是XSS「同源策略」問題。

我唯一的解決方案(我認爲)是通過代理(php代碼)來完成的,但我不希望這樣做會影響性能。

有人知道這個問題的替代/修復嗎?

注意:更新IE8不是一個選項,因爲我想在沒有更新的情況下測試它。

一個非常類似的問題,以我的: http://forum.jquery.com/topic/jquery-ui-tabs-ie8-and-injecting-elements-into-dom

回答

5

(我建議檢查我這個答案,再發表列表)

促進這一進程,我把CORS插件並修改它。如果您僅使用$ .get和$ .post,則不需要修改現有的Jquery代碼。我在IE8中測試它,並且按預期工作。其餘的瀏覽器將使用普通的JQuery調用。 您甚至可以按需添加此代碼(使用條件標籤)。 閱讀最初的評論以獲取更多信息。我希望它可以幫助...

下面是代碼(例如保存爲jquery.xdomain.js):

/* 
* 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); 

鏈接:

+0

謝謝!但是,最近在使用這種方法來處理邊緣情況時,我發現它稍微打破了'$ .get'和'$ .post'的本地功能,它們每個都返回一個jqXHR對象。通過修改代碼中的try塊可以很容易地修復這個問題以讀取'return $ ._ get(url,data,callback,type);'和'return $ ._ post(url,data,callback,type);' – itsmequinn 2013-01-17 20:09:20

-1

我要在這裏跟jAndy同意,這是非常不可能的,你得到了它的所有工作。 同樣的原產地政策適用(http://en.wikipedia.org/wiki/Same_origin_policy),您最好的辦法是編寫您的腳本投票的本地代理,然後讓代理進行跨域調用。

8

對不起,如果我的英文不是很好,我可以看到我是不太清楚......我的一個主要關注的問題是由其他人在這裏解釋:http://http://forum.jquery.com/topic/cross-domain-ajax-and-ie

那麼,有什麼替代的存在呢?

1)XDomainRequest

我個人認爲這是落實在IE8 +跨站點腳本(因爲它是原生支持)的最佳方式。唯一的問題是,這是微軟唯一的方式。但是與IE系列一樣,我們可以輕鬆擴展JQuery ajax功能。

根據文檔,您將需要在domain1中指定一些額外的標頭。TLD,for example, in PHP這樣的:

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

也許下一個選擇是提供XDomainRequest的jQuery的執行有用的;

更新(一):有一個XDR library(非jQuery的)的XHR類,使該「替換」它跨瀏覽器,它是基於在pmxdr client library。我還沒有嘗試過。

2)CORS

該插件的唯一問題是,不完全是因爲它的功能被命名爲不同的擴展,所以你需要更改您的密碼或換行插件。

更新(b):我修改了CORS插件以使其更容易。檢查我的其他答案以獲取代碼。

3)JsonP in JQuery

這應該是解決我的問題(因爲我有兩個服務器的控制權),最簡單的方法。本地化的大多數瀏覽器都支持跨站點腳本,只有在使用json格式的情況下(我相信xml也可以使用)。在這種情況下使用$ .getJSON()函數。爲了使它工作,你需要指定(如文檔狀態)callback =?在URL中,例如:

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

「?」 「回調」將與標識所取代......在你的PHP文件後,你需要獲得該標識符和環繞JSON的代碼是這樣的:

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

(我從here那個例子)

這種方法的問題是,如果你想只檢索HTML,它必須位於一個JSON對象內,從而使過程有點複雜的和壓倒一切。

4)jquery.jsonp plugin

如果你需要額外的驗證和功能在JQuery的本地JSONP支持,那麼試試這個插件,它也將簡化這個過程。

5)xdomainajax

此插件使用使用雅虎的服務YQL,在任何網頁(或其中的一部分)可以被轉換成JSON,從而能夠將其導入到JavaScript的一個有趣的形式給出。此方法適用於無法更改原點格式的情況。

6)flXHR

此解決方案使用閃光(SWF)來實現的魔法。我可以說這是一種非常快速的方式來實現幾乎完全跨瀏覽器的實現(因爲它依賴於閃存支持)。這種方法可能適用於閃存將存在的那些站點(當然)。但是,如果您的網站不需要使用閃光燈,那麼這將成爲主要缺點,因爲用戶應該安裝閃光燈才能使其工作。

7)xdajax

該方案基於在與 「閃電俠」 的做法YUI實現在一起。

8) 如果以上選項都不適合您,請記住您仍然可以使用插入標籤的舊技巧來導入JS代碼。 9)將IE安全降至最低也解決了這個問題。但我認爲這樣不會有好消息:「請降低您的安全設置,以便使用本網站」...大聲笑

我希望這可以幫助其他人在類似的情況。

+0

優秀的寫作。 – 2010-11-03 11:18:37