JQuery $.ajax не работает в 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);
    }
});

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

Ответ 1

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

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

EDIT (2013-08-22)

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

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

Вместо того, чтобы реализовывать версию XMLHttpRequest CORS, команда IE отправилась с собственным уместным объектом, названным XDomainRequest. Использование XDomainRequest было упрощено из XMLHttpRequest, добавив больше событий (с onload, возможно, самым важным).

У этой реализации есть несколько ограничений, связанных с ней. Например, куки файлы не отправляются при использовании этого объекта, что может быть головной болью для сеансов на основе файлов 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();

Ответ 2

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

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

После этого else, если тесты для 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);
            }
        });
    }
}

Ответ 3

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

Ответ 5

Добавьте дополнительный транспорт в jquery для IE. (Просто добавьте этот код в свой script в конце)

$.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 для кросс-домена.

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

Ответ 7

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

  • убедитесь, что вы используете один и тот же протокол для запросов (HTTP → HTTP или HTTPS → HTTPS), Ayush Gupta дал ссылку на информацию о проблемах
  • обрабатывать события 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();
            }
        };
    });
}

Ответ 8

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

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

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

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

Ответ 9

@Furqan Не могли бы вы сообщить мне, протестировали ли вы это методом HTTP POST,

Так как я также работаю над такой же ситуацией, но я не могу отправить данные в другой домен.

Но после прочтения этого это было довольно просто... только вам нужно забыть о OLD-браузерах. Я даю код для отправки с помощью метода 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);
}

Ответ 10

Заметьте, добавив

$.support.cors = true;

было достаточно для принудительного вызова $.ajax для работы с IE8

Ответ 11

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 поддерживают такие запросы.

Ответ 12

У меня такая же проблема в 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.

Ответ 13

У меня была аналогичная проблема в 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
            });
        }
    }

Ответ 14

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

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

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