Jquery $.ajax не работает в IE при междоменных вызовах

Я делаю междоменный запрос, используя $.ajax. Он работает в Firefox и Chrome, но не вызывает вызов в IE 7 или 8. Может ли кто-нибудь сказать мне, что не так со следующим?

  1. Я использовал JSON и JSONP (которые я прекратил использовать из-за некоторых пользовательских ограничений).
  2. Я уже использую заголовок Allow-access-control-origin на своем сайте. (Без них Chrome и Firefox не выполняли успешных запросов.)
  3. Я уже пробовал 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);
    }
});

Я пробовал различные советы, представленные на нескольких сайтах, но пока не повезло.


person Furqan Hameedi    schedule 29.07.2010    source источник
comment
Релевант: stackoverflow.com/a/12014195/545328   -  person 65Fbef05    schedule 18.08.2012


Ответы (14)


Не могли бы вы проверить, связана ли проблема с IE с отсутствием определения зон безопасности для разрешения междоменных запросов? Объяснение см. на этой странице Microsoft.

OTOH, на этой странице упоминается, что IE7 и ранее не мог выполнять междоменные вызовы, но IE8 может, используя объект, отличный от XMLHttpRequest, который использует JQuery. Не могли бы вы проверить, работает ли XDomainRequest?

ИЗМЕНИТЬ (2013-08-22)

Вторая ссылка мертва, поэтому я пишу здесь часть информации, взятой с обратная машина:

XDomainRequest Поддерживается: IE8

Вместо реализации CORS-версии XMLHttpRequest команда IE использовала собственный собственный объект с именем 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();
person Luciano    schedule 01.08.2010
comment
Спасибо, Лучано, я проверил с помощью XDomainRequest, и для IE8 это сработало, хотя мне нужно написать отдельный скрипт специально для IE8. - person Furqan Hameedi; 02.08.2010
comment
да, делаю почти то же самое, но используя $.ajax для всех браузеров, кроме IE8, $.ajax работает в IE6, IE7, FF3.5 и Chrome, но для IE8 написан тот же код XdomainRequest. - person Furqan Hameedi; 04.08.2010
comment
Сегодня я столкнулся с другим решением моей проблемы, так как в IE 8 код работает, просто отправив следующий заголовок Header Name = p3p, VALUE = CP = IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT - person Furqan Hameedi; 01.02.2011
comment
как насчет примера. вы добавили это в функцию beforeSend? - person Anthony; 01.11.2011
comment
@Furqan Это не работает. Только что протестировал IE8, Windows 7 - проблема в том, что jQuery даже не начинает транзакцию... - person tkone; 02.04.2012
comment
IE требует гораздо больше усилий, чем другие браузеры, чтобы Cors работал. У меня была та же проблема, но я исправил ее с помощью forum.jquery.com/topic /cross-domain-ajax-and-ie, где есть блок кода, который вы можете добавить, чтобы решить проблему. - person daveagp; 30.05.2012
comment
@Furqan Установка заголовка P3P не имеет ничего общего с разрешением междоменных запросов. Этот заголовок response касается того, будет ли данный файл cookie установлен или заблокирован как угроза конфиденциальности. - person EricLaw; 15.03.2013
comment
Вторая ссылка (actionmonitor.co.uk) не работает. - person ashack; 22.08.2013

Для IE8 и IE9 вам необходимо использовать XDomainRequest (XDR). Если вы посмотрите ниже, вы увидите, что это похоже на форматирование $.ajax. Насколько мои исследования помогли мне, я не могу заставить этот междоменный режим работать в IE6 и 7 (все еще ищу обходной путь для этого). XDR впервые появился в IE8 (и в IE9 тоже). Итак, сначала я тестирую 6/7 и не использую AJAX.

IE10+ может нормально выполнять междоменные операции, как и все другие браузеры (поздравляю Microsoft... вздох)

После этого else if проверяет XDomainRequest в окне (очевидно, лучше, чем анализ браузера) и таким образом выполняет запрос JSON AJAX, в противном случае ELSE обычно делает это с $.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);
            }
        });
    }
}
person Mark Pieszak - Trilon.io    schedule 29.06.2012
comment
Если бы я только мог «пометить как любимый» ответ вместо вопроса :) - person Vikram Deshmukh; 07.07.2014
comment
Он отлично работает, но что мне делать с запросами POST в IE8 и IE9? - person Surya; 19.07.2014
comment
@Surya Посмотрите на этот пример: stackoverflow.com/a/12233050/1492009. Эту функцию я сделал давно, с тех пор я сделал ее гораздо более универсальной/передавая в какой тип (get/post). Но вы просто передаете его как обычно: xdr.open('POST', url); - person Mark Pieszak - Trilon.io; 23.07.2014
comment
Передача аутентификации клиента не будет работать с XDomainRequest. (Если вы ищете замену xhrFields:{withCredentials:true} ) Ни проверка подлинности, ни файлы cookie не будут передаваться согласно сообщению ниже blogs.msdn.com/b/ieinternals/archive/2010/05/13/ - person Dan; 04.02.2015
comment
Что бы это ни стоило, кажется, что data.firstChild.textContent не является допустимым значением в разделе отката ошибки функции onload. Я заменил его на xdr.responseText.firstChild.textContent..., который должен давать более согласованные результаты и фактически проходить линтинг. - person Crates; 24.01.2017

Jquery сделает это за вас, нужно только установить $.support.cors = true; Тогда междоменный запрос отлично работает во всех браузерах для пользователей jquery.

person Anand    schedule 17.07.2012
comment
если вы посмотрите на дату, когда был задан этот вопрос, в то время jquery не использовался для поддержки этого атрибута, он был введен позже, и все же он не выполняет сценарий, просто установив для него значение true, есть настройки на стороне сервера, которые вам также нужно настроить. - person Furqan Hameedi; 17.07.2012
comment
какие заголовки сервера нужно отправить? - person Michael Yagudaev; 05.01.2013
comment
$.support.cors = истина; - похоже, не работает в IE8 даже с последней версией jquery. - person teon; 21.03.2013
comment
Это неверно для IE 8 или 9. Вам все равно нужно использовать XDomainRequest. Просто установить $.support.cors = true недостаточно. - person d512; 23.09.2013
comment
Не влияет на IE8, jQuery 1.10.2 :( - person Ain Tohvri; 14.01.2014
comment
Это решение работает для меня, используя jQuery 1.11.0 в IE9, установленном в стандартном режиме IE8. - person Greg Prisament; 03.06.2015

Просто установите этот подключаемый модуль jQuery: jQuery Cross-Domain AJAX для IE8

Этот подключаемый модуль размером 1,4 КБ сразу работает в Internet Explorer 8 и 9.

Включите плагин после jQuery и вызовите свой запрос ajax как обычно. Больше ничего не требуется.

person Bradley Flood    schedule 26.09.2013
comment
Спасибо, дорогая, за руку помощи. Ваш ответ может помочь кому-то, кто столкнулся с той же проблемой. - person Furqan Hameedi; 26.09.2013
comment
У меня работало в IE7-9 на jQuery 1.8.3. Этот плагин чрезвычайно трудно найти. Если кто-то наткнется на это, пожалуйста, дайте этому ответу столько голосов, которых он заслуживает. - person Anthony DiSanti; 06.06.2014
comment
Просто примечание: github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest не позволяет межпротокольные вызовы. - person Jason D.; 08.10.2015

Добавьте дополнительный транспорт в 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 для междоменного запроса AJAX.

Ваше здоровье.

person Jay Dave    schedule 23.08.2012
comment
Когда этот вопрос был задан в 2010 году, jquery не был достаточно зрелым, ваше решение могло решить проблему, но сейчас немного поздно. В любом случае спасибо за руку помощи. - person Furqan Hameedi; 24.08.2012

Другим посетителям здесь будет полезно прочитать http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx, в котором говорится об ограничениях XDomainRequest.

person Ayush Gupta    schedule 15.08.2012

Для тех, у кого все еще может быть эта проблема с использованием jQuery 2.0 (я знаю, что у меня есть), Джей Дэйв написал лучший обходной путь jQuery, но у меня все еще есть несколько вещей, которые нужно добавить к его коду, а именно:

  • убедитесь, что вы используете один и тот же протокол для запросов (HTTP -> HTTP или HTTPS -> HTTPS), Аюш Гупта дал ссылку на известные проблемы
  • обрабатывать события onprogress с помощью функции отсутствия операций (это предотвратит прерывание запросов 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();
            }
        };
    });
}
person alecs.popa    schedule 31.05.2013
comment
У меня не работает на jQuery 1.11.1, но из-за IE: нет разумного сообщения об ошибке :'-( Однако оригинальный плагин работает: github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js - person Simon Steinberger; 28.11.2014

Обратите внимание, добавляя

$.support.cors = true;

было достаточно, чтобы вызовы $.ajax работали в IE8

person jpantona    schedule 18.11.2013
comment
спасибо за вашу помощь немного. Ваш ответ может помочь другим людям, которые ищут, для меня уже слишком поздно, так как на момент вопроса у jquery не было такой поддержки IE8. - person Furqan Hameedi; 19.11.2013
comment
Для этого свойства уже установлено значение true, но оно по-прежнему не работает в IE8. - person Lev; 12.12.2017

Просто добавьте "?callback=?" (или "&callback=?") на ваш URL:

$.getJSON({
    url:myUrl + "?callback=?",
    data: myData,
    success: function(data){
        /*My function stuff*/        
    }
});

При выполнении вызовов (со всем остальным, правильно настроенным для междоменного, как указано выше) это вызовет правильное форматирование JSONP.

Более подробное объяснение можно найти в ответе здесь.

person Randy Hall    schedule 15.03.2013
comment
@Furqan Просто публикую это для всех, кто сталкивается с этой проблемой (например, я недавно). - person Randy Hall; 16.03.2013
comment
У меня работает... на одном из самых загруженных розничных магазинов на планете. У тебя есть скрипка или что-то, что мы можем увидеть? - person Randy Hall; 20.11.2013
comment
Вы неправильно поняли проблему. Эта проблема связана с поддержкой IE8 междоменных вызовов AJAX, которую можно решить, только обратившись к решениям, включающим CORS и XDomainRequest (например, github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest, который решил проблему для меня). Если бы проблему можно было решить, просто добавив дополнительный аргумент в QueryString, не думаете ли вы, что ваш ответ был бы принятым? И тебе не кажется, что это была бы довольно большая дыра в безопасности, если бы это действительно был ответ? - person James McCormack; 22.11.2013
comment
Лучше? Не ожидал, что это появится через 8 месяцев ... некоторые люди, по-видимому, сочли это достаточно полезным, чтобы проголосовать. - person Randy Hall; 22.11.2013
comment
@JamesMcCormack добавил ссылку на другой ответ. Пытаясь решить проблему, я обнаружил, что этот ответ работает, но он был хорошо спрятан. Я разместил ответ здесь, чтобы другие люди с такой же проблемой, которые искали то же самое, могли найти эту информацию. - person Randy Hall; 22.11.2013

@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);
}
person Sandesh Daddi    schedule 15.10.2011
comment
Проблема здесь была в старых браузерах, а не в почтовом запросе. В любом случае спасибо за вашу помощь. - person Furqan Hameedi; 17.10.2011

Microsoft всегда прокладывает пагубную борозду (по крайней мере, в IE):

http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

CORS работает с XDomainRequest в IE8. Но IE 8 не поддерживает Preflighted или Credentialed Requests, в то время как Firefox 3.5+, Safari 4+ и Chrome поддерживают такие запросы.

person Raman    schedule 10.08.2010

У меня такая же проблема в IE, я решил ее заменой:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

To

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

Так что в основном обновите версию jquery.

person KingBowen    schedule 21.08.2013

У меня была аналогичная проблема в IE9, когда некоторые вызовы CORS прерывались, а другие — нет. Мое приложение также зависит от интерфейса обещания, поэтому приведенные выше предложения XDomainRequest не были ТОЧНО тем, что мне нужно, поэтому я добавил отложенный обходной путь service.get для 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
            });
        }
    }
person David Savage    schedule 27.08.2013

Трудно сказать из-за отсутствия форматирования в вопросе, но я думаю, что вижу две проблемы с вызовом ajax.

1) application/x-www-form-urlencoded для contentType должен быть в кавычках

2) Должна быть запятая, разделяющая параметры contentType и async.

person KallDrexx    schedule 29.07.2010
comment
Привет Калл, спасибо за ответ. Я тоже попробовал ваше предложение, в вопросе он был опечатан. Он отлично работает в Chrome и Firefox для предварительных запросов, но не работает в IE. Но не можете сказать, почему? пожалуйста, поделитесь со мной еще советами, если у вас есть. - person Furqan Hameedi; 01.08.2010