Jquery $.ajax 在跨域调用时在 IE 中失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3362474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jquery $.ajax fails in IE on cross domain calls
提问by Furqan Hameedi
I am doing a cross domain request using $.ajax
. It works on Firefox and Chrome, but does not issue a call on IE 7 or 8. Can anyone tell me what's wrong with the following?
我正在使用$.ajax
. 它适用于 Firefox 和 Chrome,但不会在 IE 7 或 8 上发出调用。谁能告诉我以下有什么问题?
- I have used JSON and JSONP (which I stopped using, due to some custom restrictions).
- I am already using
Allow-access-control-origin
header on my site. (Without those, Chrome and Firefox were not making successful requests.) - I have already tried https://developer.mozilla.org/en/http_access_control
- 我使用过 JSON 和 JSONP(由于一些自定义限制,我停止使用它们)。
- 我已经
Allow-access-control-origin
在我的网站上使用标题。(没有这些,Chrome 和 Firefox 就无法成功发出请求。) - 我已经尝试过https://developer.mozilla.org/en/http_access_control
Code:
代码:
$.ajax({
type: 'GET',
url: "http://anotherdomain.com/Service/GetControl?id=" + zoneID,
cache: false,
contentType: "application/x-www-form-urlencoded",
async: false,
beforeSend: function (request) {
//alert('before send');
//request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
//request.setRequestHeader("X-PINGOTHER", "pingpong");
} ,
success: function (data, status) {
//alert("Data returned :" + data);
//alert("Status :" + status);
if (status == "success" && data != "")
$("#" + div.id).append(data);
else
$("#" + div.id).attr("style", "display:none;");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
alert(errorThrown);
}
});
I have tried various tips present on multiple sites, but no luck yet.
我已经尝试了多个网站上的各种提示,但还没有运气。
采纳答案by Luciano
Could you check if the problem with IE relies on not defining security zones to allow cross domain requests? See this microsoft pagefor an explanation.
您能否检查一下 IE 的问题是否依赖于未定义安全区域以允许跨域请求?有关解释,请参阅此 microsoft 页面。
OTOH, this pagementions that IE7 and eariler cannot do cross domain calls, but IE8 can, using a different object than XMLHttpRequest, the one JQuery uses. Could you check if XDomainRequest works?
OTOH,此页面提到 IE7 和早期版本不能进行跨域调用,但 IE8 可以使用与 XMLHttpRequest 不同的对象,即 JQuery 使用的对象。你能检查一下 XDomainRequest 是否有效吗?
EDIT (2013-08-22)
编辑 (2013-08-22)
The second link is dead, so I'm writing here some of its information, taken from the wayback machine:
第二个链接已经失效,所以我在这里写下它的一些信息,取自回归机器:
XDomainRequest Supported: IE8
Rather than implement the CORS version of XMLHttpRequest, the IE team have gone with there own propriety object, named XDomainRequest. The usage of XDomainRequest has been simplified from XMLHttpRequest, by having more events thrown (with onload perhaps being the most important).
This implementation has a few limitations attached to it. For example, cookies are not sent when using this object, which can be a headache for cookie based sessions on the server side. Also, ContentType can not be set, which poses a problem in ASP.NET and possibly other server side languages (see http://www.actionmonitor.co.uk/NewsItem.aspx?id=5).
var xdr = new XDomainRequest(); xdr.onload = function() { alert("READY"); }; xdr.open("GET", "script.html"); xdr.send();
支持 XDomainRequest:IE8
IE 团队没有实现 XMLHttpRequest 的 CORS 版本,而是使用了自己的专有对象,名为 XDomainRequest。XDomainRequest 的使用已从 XMLHttpRequest 简化,通过抛出更多事件(onload 可能是最重要的)。
这个实现有一些限制。例如,使用此对象时不会发送 cookie,这对于服务器端基于 cookie 的会话来说可能是一个令人头疼的问题。此外,无法设置 ContentType,这在 ASP.NET 和可能的其他服务器端语言中造成问题(请参阅http://www.actionmonitor.co.uk/NewsItem.aspx?id=5)。
var xdr = new XDomainRequest(); xdr.onload = function() { alert("READY"); }; xdr.open("GET", "script.html"); xdr.send();
回答by Mark Pieszak - Trilon.io
For IE8 & IE9 you need to use XDomainRequest (XDR). If you look below you'll see it's in a sort of similar formatting as $.ajax. As far as my research has got me I can't get this cross-domain working in IE6 & 7 (still looking for a work-around for this). XDR first came out in IE8 (it's in IE9 also). So basically first, I test for 6/7 and do no AJAX.
对于 IE8 和 IE9,您需要使用 XDomainRequest (XDR)。如果你往下看,你会看到它的格式与 $.ajax 类似。就我的研究而言,我无法让这个跨域在 IE6 和 7 中工作(仍在为此寻找解决方法)。XDR 首先出现在 IE8 中(它也在 IE9 中)。所以基本上首先,我测试 6/7 并且不做 AJAX。
IE10+ is able to do cross-domain normally like all the other browsers (congrats Microsoft... sigh)
IE10+ 可以像其他浏览器一样正常跨域(恭喜微软……叹气)
After that the else if tests for 'XDomainRequest in window (apparently better than browser sniffing) and does the JSON AJAX request that way, other wise the ELSE does it normally with $.ajax.
之后 else if 测试窗口中的 'XDomainRequest (显然比浏览器嗅探更好)并以这种方式执行 JSON AJAX 请求,否则 ELSE 通常使用 $.ajax 执行它。
Hope this helps!! Took me forever to get this all figured out originally
希望这可以帮助!!我花了很长时间才弄明白这一切
Information on the XDomainRequest object
// call with your url (with parameters)
// 2nd param is your callback function (which will be passed the json DATA back)
crossDomainAjax('http://www.somecrossdomaincall.com/?blah=123', function (data) {
// success logic
});
function crossDomainAjax (url, successCallback) {
// IE8 & 9 only Cross domain JSON GET request
if ('XDomainRequest' in window && window.XDomainRequest !== null) {
var xdr = new XDomainRequest(); // Use Microsoft XDR
xdr.open('get', url);
xdr.onload = function () {
var dom = new ActiveXObject('Microsoft.XMLDOM'),
JSON = $.parseJSON(xdr.responseText);
dom.async = false;
if (JSON == null || typeof (JSON) == 'undefined') {
JSON = $.parseJSON(data.firstChild.textContent);
}
successCallback(JSON); // internal function
};
xdr.onerror = function() {
_result = false;
};
xdr.send();
}
// IE7 and lower can't do cross domain
else if (navigator.userAgent.indexOf('MSIE') != -1 &&
parseInt(navigator.userAgent.match(/MSIE ([\d.]+)/)[1], 10) < 8) {
return false;
}
// Do normal jQuery AJAX for everything else
else {
$.ajax({
url: url,
cache: false,
dataType: 'json',
type: 'GET',
async: false, // must be set to false
success: function (data, success) {
successCallback(data);
}
});
}
}
回答by Anand
Jquery does this for you, only thing is to set $.support.cors = true;
Then cross domain request works fine in all browsers for jquery users.
$.support.cors = true;
jquery为你做这件事,唯一的事情就是设置然后跨域请求在 jquery 用户的所有浏览器中都能正常工作。
回答by Bradley Flood
Simply install this jQuery Plugin: jQuery Cross-Domain AJAX for IE8
只需安装这个 jQuery 插件:jQuery Cross-Domain AJAX for IE8
This 1.4kb plugin works right away in Internet Explorer 8 and 9.
这个 1.4kb 的插件可以立即在Internet Explorer 8 和 9 中使用。
Include the plugin after jQuery, and call your ajax request as normal. Nothing else required.
在 jQuery 之后包含插件,并正常调用您的 ajax 请求。没有其他要求。
回答by Jay Dave
Add extra transport to jquery for IE. ( Just add this code in your script at the end )
为 IE 的 jquery 添加额外的传输。(只需在脚本最后添加此代码)
$.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {
if(jQuery.browser.msie && window.XDomainRequest) {
var xdr;
return {
send: function( headers, completeCallback ) {
// Use Microsoft XDR
xdr = new XDomainRequest();
xdr.open("get", options.url);
xdr.onload = function() {
if(this.contentType.match(/\/xml/)){
var dom = new ActiveXObject("Microsoft.XMLDOM");
dom.async = false;
dom.loadXML(this.responseText);
completeCallback(200, "success", [dom]);
}else{
completeCallback(200, "success", [this.responseText]);
}
};
xdr.ontimeout = function(){
completeCallback(408, "error", ["The request timed out."]);
};
xdr.onerror = function(){
completeCallback(404, "error", ["The requested resource could not be found."]);
};
xdr.send();
},
abort: function() {
if(xdr)xdr.abort();
}
};
}
});
This solved my problem with Jquery $.ajax failing for Cross Domain AJAX request.
这解决了我的跨域 AJAX 请求的 Jquery $.ajax 失败问题。
Cheers.
干杯。
回答by Ayush Gupta
Others coming around here might do well to read http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspxwhich talks about limitations of XDomainRequest
来到这里的其他人可能会很好地阅读http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx,其中讨论了 XDomainRequest 的限制
回答by alecs.popa
For anyone whom might still have this problem using jQuery 2.0 (I know I do), Jay Dave wrote the best jQuery workaround but I still have a few things to add to his code namely:
对于使用 jQuery 2.0 仍然有这个问题的人(我知道我有),Jay Dave 写了最好的 jQuery 解决方法,但我仍然有一些东西要添加到他的代码中,即:
- make sure you are using the same protocol for requests (HTTP -> HTTP or HTTPS -> HTTPS), Ayush Gupta gave a link to knows issues
- handle the "onprogress" events with a no-op function (this will prevent IE from abording the requests after it receives the first bits from the server.
- 确保您对请求使用相同的协议(HTTP -> HTTP 或 HTTPS -> HTTPS),Ayush Gupta 提供了一个链接来了解问题
- 使用无操作功能处理“onprogress”事件(这将防止 IE 在从服务器接收到第一位后放弃请求。
The complete code is below:
完整代码如下:
// add ajax transport method for cross domain requests when using IE9
if('XDomainRequest' in window && window.XDomainRequest !== null) {
$.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {
// verify if we need to do a cross domain request
// if not return so we don't break same domain requests
if (typeof options.crossDomain === 'undefined' || !options.crossDomain) {
return;
}
var xdr;
return {
send: function( headers, completeCallback ) {
// Use Microsoft XDR
xdr = new XDomainRequest();
xdr.open("get", options.url); // NOTE: make sure protocols are the same otherwise this will fail silently
xdr.onload = function() {
if(this.contentType.match(/\/xml/)){
var dom = new ActiveXObject("Microsoft.XMLDOM");
dom.async = false;
dom.loadXML(this.responseText);
completeCallback(200, "success", [dom]);
} else {
completeCallback(200, "success", [this.responseText]);
}
};
xdr.onprogress = function() {};
xdr.ontimeout = function(){
completeCallback(408, "error", ["The request timed out."]);
};
xdr.onerror = function(){
completeCallback(404, "error", ["The requested resource could not be found."]);
};
xdr.send();
},
abort: function() {
if(xdr) xdr.abort();
}
};
});
}
回答by jpantona
Note, adding
注意,添加
$.support.cors = true;
was sufficient to force $.ajax calls to work on IE8
足以强制 $.ajax 调用在 IE8 上工作
回答by Randy Hall
Simply add "?callback=?" (or "&callback=?") to your url:
只需添加“?callback=?” (或“&callback=?”)到您的网址:
$.getJSON({
url:myUrl + "?callback=?",
data: myData,
success: function(data){
/*My function stuff*/
}
});
When doing the calls (with everything else set properly for cross-domain, as above) this will trigger the proper JSONP formatting.
在进行调用时(如上所述,为跨域正确设置了其他所有内容)这将触发正确的 JSONP 格式。
More in-depth explanation can be found in the answer here.
可以在此处的答案中找到更深入的解释。
回答by Sandesh Daddi
@Furqan Could you please let me know whether you tested this with HTTP POST method,
@Furqan 您能否告诉我您是否使用 HTTP POST 方法对此进行了测试,
Since I am also working on the same kind of situation, but I am not able to POST the data to different domain.
由于我也在处理同样的情况,但我无法将数据发布到不同的域。
But after reading thisit was quite simple...only thing is you have to forget about OLD browsers. I am giving code to send with POST method from same above URL for quick reference
但是读完 这篇文章后就很简单了……唯一的问题是您必须忘记旧浏览器。我正在提供代码以使用来自上述 URL 的 POST 方法发送以供快速参考
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("POST", "http://www.sanshark.com/");
var content = "name=sandesh&lastname=daddi";
if (request){
request.onload = function(){
//do something with request.responseText
alert(request.responseText);
};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", content.length);
request.send(content);
}