Firefox和Chrome中的一切都很完美,但IE8除外(8.0.6001.18702)
这是测试代码(Jquery 1.4.2)($ .post的问题):
$(function() { $.get("http://domain2.tld/some.php", {}, function(response) { alert(response); }); });
此代码在domain1.tld中执行,并从domain2.tld加载,这样:
我在IE8中收到"Permission denied"消息.到目前为止,我尝试过没有成功:
1)在domain1.tld中添加(php代码):
header("X-XSS-Protection: 0");
2)在IE8选项中禁用XSS过滤器.
我正在使用IE8调试器,它在第5113行显示错误:
xhr.open(type, s.url, s.async);
如果不是调用$ .get(domain2.tld ...),我调用$ .get(domain1.tld ...)没有错误,这向我确认这是一个XSS"同源策略"问题.
我唯一的解决方案(我认为)是通过代理(PHP代码)来实现的,但我不愿意这样做,因为它会影响性能.
有人知道这个问题的替代/解决方法吗?
注意:更新IE8不是一个选项,因为我想在没有更新的情况下测试它.
我的一个非常类似的问题:http: //forum.jquery.com/topic/jquery-ui-tabs-ie8-and-injecting-elements-into-dom
我很抱歉,如果我的英语不完美,我可以看到我不够清楚......我的主要关注之一是其他人在这里解释的:http://forum.jquery.com/topic/cross-domain -ajax和-IE
那么,存在哪种替代方案?
1)XDomainRequest
我个人认为这是在IE8 +中实现跨站点脚本的最佳方式(因为它本身支持).唯一的问题是,这是一种仅限Microsoft的方式.但是与IE系列一样多的其他东西我们可以轻松扩展JQuery ajax功能.
根据文档,您需要在domain1.tld中指定一些额外的头文件,例如,在PHP中,如下所示:
header("Access-Control-Allow-Origin: http://domain2.tld"); //use * for any
也许下一个替代方案对于提供XDomainRequest的jquery实现很有用;
更新(a):有一个XDR库(非jquery)"替换"XHR类使其跨浏览器,它基于pmxdr客户端库.我还没有尝试过.
2)CORS
这个插件的唯一问题是它不完全是一个扩展,因为它的函数命名不同,所以你需要更改你的代码或包装该插件.
更新(b):我修改了CORS插件以使其更容易.检查我的其他答案以获取代码.
3)JQuery中的JsonP
这应该是解决我的问题最简单的方法(因为我控制了两个服务器).本地大多数浏览器都支持跨站点脚本,只有在使用json格式时(我相信也可以使用xml).在这种情况下,使用$ .getJSON()函数.为了使它工作,你需要指定(如文档所述)callback =?在URL中,例如:
$.getJSON("http://domain2.tld/index.php?callback=?",funciton(res){ ... });
"?" 在"回调"将被替换为标识符...在您的php文件中,您需要获取该标识符并围绕Json代码,如下所示:
print_r($_GET["callback"])."(".json_encode($mydata).");";
(我从这里得到了这个例子)
这种方法的问题在于,如果你只想检索HTML,它必须驻留在一个json对象中,从而使这个过程变得更加复杂和压倒性.
4)jquery.jsonp插件
如果您需要对JQuery中的本机JSONP支持进行额外的验证和功能,那么请尝试使用此插件,这也将简化该过程.
5)xdomainajax
这个插件使用Yahoo的服务YQL使用一个有趣的方法,其中任何网页(或其中的一部分)都可以转换为Json,从而可以将其导入到javascript中.此方法适用于无法更改原始格式的情况.
6)flXHR
这个解决方案使用flash(swf)来实现魔力.我可以说这是实现几乎完全跨浏览器实现的一种非常快速的方式(因为它依赖于闪存支持).这种方法对于那些存在闪光的场所(肯定)来说可能是理想的.但是,如果您的站点不需要闪存,那么这将成为主要的缺点,因为用户应该安装闪存以使其正常工作.
7)xdajax
该解决方案基于YUI实现以及"Flash"方法.
8)如果以前的选项都不适合你,请记住你仍然可以使用插入标记的旧技巧来导入JS代码.
9)将IE安全性降至最低也解决了问题.但我认为这样的消息不会很好:"请降低您的安全设置以便使用此网站"...大声笑
我希望这可以帮助处于类似情况的其他人.
(我建议查看我在回答之前发布的列表)
为了方便这个过程,我使用了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: * * * * 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);
链接:
proxy_xmlhttp.js
PHP Post方法
在PHP中导入XDR数据