Jquery $ .ajax не работает в IE при междоменных вызовах - PullRequest
64 голосов
/ 29 июля 2010

Я делаю междоменный запрос, используя $.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);
    }
});

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

Ответы [ 14 ]

61 голосов
/ 29 июня 2012

Для 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);
            }
        });
    }
}
32 голосов
/ 01 августа 2010

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

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

РЕДАКТИРОВАТЬ (2013-08-22)

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

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

Вместо того, чтобы реализовывать версию XMLHttpRequest для CORS, команда 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();
23 голосов
/ 17 июля 2012

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

20 голосов
/ 26 сентября 2013

Просто установите этот плагин jQuery: Междоменный домен JQuery AJAX для IE8

Этот плагин 1,4 КБ работает сразу в Internet Explorer 8 и 9 .

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

7 голосов
/ 23 августа 2012

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

Приветствие.

5 голосов
/ 15 августа 2012

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

3 голосов
/ 31 мая 2013

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

  • убедившись, что вы используете тот же протокол для запросов (HTTP -> HTTP или HTTPS -> HTTPS), Аюш Гупта дал ссылку на известные проблемы
  • обрабатывает события 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();
            }
        };
    });
}
2 голосов
/ 15 марта 2013

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

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

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

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

1 голос
/ 19 ноября 2013

Примечание, добавление

$.support.cors = true;

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

1 голос
/ 16 октября 2011

@ 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...