Jquery $.Аякс не в IE на междоменных вызовов
Я делаю кросс-доменный запрос с помощью $.ajax
. Он работает на Firefox и Chrome, но не выдает вызов на IE 7 или 8. Может кто-нибудь сказать мне, что не так со следующим?
- я использовал JSON и JSONP (которые я перестал использовать из-за некоторых пользовательских ограничений).
- Я уже использую
Allow-access-control-origin
заголовок на моем сайте. (Без них Chrome и Firefox не делали успешных запросов.) - Я уже пробовал https://developer.mozilla.org/en/http_access_control
код:
$.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);
}
});
Я пробовал различные советы, присутствующие на нескольких сайтах, но пока безуспешно.
14 ответов:
Не могли бы вы проверить, если проблема с IE зависит от не определения зон безопасности, чтобы разрешить междоменные запросы? смотрите эту страницу microsoft для объяснений.
ото на этой странице упоминает, что IE7 и eariler не могут выполнять междоменные вызовы, но IE8 может использовать другой объект, чем XMLHttpRequest, который использует JQuery. Не могли бы вы проверить, работает ли XDomainRequest?
EDIT (2013-08-22)
вторая ссылка мертв, поэтому я пишу здесь часть своей информации, взятой из wayback machine:
XDomainRequest Поддерживается: IE8
вместо того, чтобы реализовать версию CORS XMLHttpRequest, команда IE пошла с собственным объектом propriety, названным 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();
для IE8 & IE9 вам нужно использовать XDomainRequest (XDR). Если вы посмотрите ниже, вы увидите, что это похоже на форматирование $.Аякс. Что касается моих исследований, я не могу заставить этот кросс-домен работать в IE6 & 7 (все еще ищу обходной путь для этого). XDR впервые вышел в IE8 (он также находится в IE9). Поэтому в основном сначала я тестирую 6/7 и не делаю AJAX.
IE10+ способен делать кросс-домен нормально, как и все другие браузеры (поздравляет Microsoft... вздох)
после этого остальное, если тесты для ' XDomainRequest в окне (по-видимому, лучше, чем обнюхивание браузера) и делает запрос JSON AJAX таким образом, по-другому это делает обычно с $.Аякс.
надеюсь, что это помогает!! Мне потребовалась вечность, чтобы все это понять изначально
информация об объекте XDomainRequest
// 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); } }); } }
Jquery делает это за вас, единственное, что нужно установить
$.support.cors = true;
тогда кросс-доменный запрос отлично работает во всех браузерах для пользователей jquery.
просто установите этот плагин jQuery:jQuery Кросс-домен AJAX для IE8
этот плагин 1.4 kb Работает сразу в Internet Explorer 8 и 9.
включите плагин после jQuery и вызовите свой запрос ajax как обычно. Больше ничего не требовалось.
добавить дополнительный транспорт в jquery для IE. (Просто добавьте этот код в свой скрипт в конце)
$.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(); } }; } });
это решило мою проблему с Jquery $.Аякс не для кросс-доменный AJAX-запрос.
Ура.
другие приходят сюда, возможно, хорошо бы прочитать http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx что говорит об ограничениях XDomainRequest
для тех, кто все еще может иметь эту проблему с помощью jQuery 2.0 (Я знаю, что делаю), Джей Дэйв написал лучший обходной путь jQuery, но у меня все еще есть несколько вещей, чтобы добавить к его коду, а именно:
- убедитесь, что вы используете один и тот же протокол для запросов (HTTP -> HTTP или HTTPS -> HTTPS), Ayush Gupta дал ссылку на knows issues
- обрабатывать события "onprogress" с функцией no-op (это предотвратит IE от прерывания запросов после того, как он получит первые биты от сервер.
полный код ниже:
// 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(); } }; }); }
просто добавить "?обратный вызов=?"(или " &callback=?") в свой адрес:
$.getJSON({ url:myUrl + "?callback=?", data: myData, success: function(data){ /*My function stuff*/ } });
при выполнении вызовов (со всем остальным, установленным правильно для междоменного, как указано выше) это вызовет правильное форматирование JSONP.
более подробное объяснение можно найти в ответе здесь.
@Furqan не могли бы вы сообщить мне, протестировали ли вы это с помощью метода HTTP POST,
поскольку я также работаю над одной и той же ситуацией, но я не могу отправлять данные в другой домен.
но после прочтения этой это было довольно просто...единственное, что вы должны забыть о старых браузерах. Я даю код для отправки с помощью метода POST из того же URL выше для быстрой справки
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); }
обратите внимание, при добавлении
$.support.cors = true;
было достаточно, чтобы заставить $.AJAX-вызовы, чтобы работать на IE8
Microsoft всегда пашет саморазрушительную (по крайней мере в IE) борозду:
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
CORS работает с XDomainRequest в IE8. Но IE 8 не поддерживает предварительные или учетные запросы, в то время как Firefox 3.5+, Safari 4+ и Chrome поддерживают такие запросы.
у меня такая же проблема в IE, я решил ее заменить:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
до
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
Так что в основном обновить версию jquery.
У меня была аналогичная проблема в IE9, где некоторые вызовы CORS прерывались, а другие-нет. мое приложение также зависит от интерфейса promise, поэтому предложения XDomainRequest выше были не совсем тем, что мне нужно, поэтому я добавил отложенный в свою службу.получить обходной путь для IE9. Надеюсь, это может быть полезно для кого-то еще, кто сталкивается с этой проблемой. :
get: function (url) { if ('XDomainRequest' in window && window.XDomainRequest !== null) { var deferred = $.Deferred(); var xdr = new XDomainRequest(); xdr.open("get", url); xdr.onload = function() { json = xdr.responseText; parsed_json = $.parseJSON(json); deferred.resolve(parsed_json); } xdr.send(); return deferred; } else { return $.ajax({ url: url, type: 'GET', dataType: 'json', crossDomain: true }); } }