Непоследовательный ответ AJAX (XDR) от IE - PullRequest
6 голосов
/ 09 марта 2011

Я делаю ajax-запрос от iframe, который вставляется на каждую страницу через плагин IE. Я использую IE 100 * междоменный запрос , потому что ajax jQuery не работает для IE. Это работает 75% времени на IE8 и 9. Остальные 25%, xdr.onload даже не срабатывают.

Сервер php выполняет свою работу ... журнал выглядит идентично, когда onload запускается и не запускается. Кроме того, xdr.onerror тоже не стреляет.

Есть идеи?

        thisURL = "http://example.com/getmsg.php?cmd=getMessage&iid=ddeb2c1228&uurl=http%3A%2F%2Fwww.cnn.com%2F&t=" + Math.random(); 

        // Use Microsoft XDR
        var xdr = new XDomainRequest();
        xdr.open("GET", thisURL);
        xdr.onload = function() {
            // this is sometimes called, sometimes not in IE
            alert('INCONSISTENT ALERT');
            callback(xdr.responseText);
        };
        xdr.send();

Ответы [ 5 ]

9 голосов
/ 14 июля 2011

У меня была очень похожая проблема: XDomainRequests не всегда выполнялся, несмотря на то, что Fiddler отображал все заголовки запросов и ответов, отправленные точно так, как я планировал.Я определил каждый обработчик событий и свойство timeout для этих объектов XDR, и ни один из обработчиков не вызывался.Инструменты разработчика F12 показали запросы как прерванные.И GET, и POST можно было прервать для нескольких разных доменов, но первый запрос всегда работал успешно.

Затем я попытался перевести вызовы на xdr.send в течение определенного времени, например:

setTimeout(function () {
    xdr.send();
}, 0);

и это сработало.Я понятия не имею, почему, но, возможно, это будет полезно кому-то еще.

7 голосов
/ 19 июня 2012

Вы правильно назвали название здесь. Опыт довольно противоречивый. Давайте пройдемся по нему ...

var xdr, err, res, foo, url;

xdr = new XDomainRequest();

err = function(){ alert("There was an error, operation aborted"); }
res = function(){ alert("Success! " + xdr.responseText); }
foo = function(){ return; }

url = "http://hello.com/here/is/the/url/?query=true&whatever=asd";

xdr.onerror = err;
xdr.ontimeout = foo;
xdr.onprogress = foo;
xdr.onload = res;
xdr.timeout = 5000;

xdr.open("get", url);
xdr.send(null);

Объект XDomainRequest обрабатывает по-разному в каждом IE.

В IE9 -> объект XDomainRequest требует , чтобы все дескрипторы получили метод. Это означает, что для таких дескрипторов, как onerror, onload, ontimeout и onprogress, нужно что-то делать. Без определения метода для этих дескрипторов вы получите сетевой ответ «операция прервана».

В IE7 / 8/9 -> XDomainRequest по умолчанию имеет значение ASYNC. Он будет выполнять код дальше вниз по стеку независимо от того, завершается объект xdr или нет. Помещение setTimeout может быть решением, но не должно быть.

В этом случае инициируйте событие и прослушайте событие, прежде чем выполнять какой-либо дополнительный код. Примером этого может быть (в jquery) ...

// call this method in xdr onload
$(document).trigger("xdr_complete");

// use this wrapper in code you want to execute after the complete of xdr
$(document).bind("xdr_complete", function(){ ... });

В IE7 / IE8 вы заметите, что он работает. IE7 и IE8 довольно «свободны» в том, что они не прерываются, когда отсутствует метод для дескрипторов.

4 голосов
/ 23 марта 2011

Обнаружил проблему в последнюю минуту.В моем случае мне нужно было указать значение тайм-аута, даже если запросы не истекали.Чтобы правильно отладить проблему XDR, я бы предложил следующий код, в котором каждое оповещение сообщает вам, что происходит с вашим кодом.Как я уже сказал, в моем случае это было пропущенное объявление timeout.Но приведенный ниже код должен отлаживать любые проблемы XDR:

       var xdr = new XDomainRequest();
            if (xdr) {
                xdr.onerror = function () {
//                    alert('xdr onerror');
                };
                xdr.ontimeout = function () {
//                    alert('xdr ontimeout');
                };
                xdr.onprogress = function () {
//                    alert("XDR onprogress");
//                    alert("Got: " + xdr.responseText);
                };
                xdr.onload = function() {
//                    alert('onload' + xdr.responseText);
                    callback(xdr.responseText);
                };
                xdr.timeout = 5000;
                xdr.open("get", thisURL);
                xdr.send();
            } else {
//                alert('failed to create xdr');
            }
0 голосов
/ 23 марта 2011
  • Прежде всего, добавьте обработчик onerror для отладки ваших вещей.Зарегистрируйте их и посмотрите, что именно происходит.
  • Во-вторых, ваш подход "math.random" ошибочен.Лучшим вариантом является использование new Date (). GetTime (), это обеспечит получение уникальных запросов с течением времени.
  • В-третьих, вы можете (вероятно, должны) использовать методы POST, чтобы обойти очевидные стандарты IEповедение на основе (;-))
0 голосов
/ 18 марта 2011

Сложно дать вам однозначный ответ.

Во-первых, вы должны попробовать использовать Fiddler , чтобы увидеть, если вы получаете какой-либо сбой сети.Это поможет вам понять, был ли на самом деле выполнен запрос и получен ответ от сервера.

Во-вторых, и я не знаю, применимо ли это, у нас недавно была проблема с кросс-доменом в IE.Код отлично работал в других браузерах - Firefox, Safari и Chrome.Проблема в этом случае оказалась в том, что запрос возвращал 404, что ожидалось.Несмотря на это, IE прекратил все выполнение в этот момент, даже наша обработка ошибок события 404 никогда не запускалась.Таким образом, вы могли бы получить то же самое здесь.Firefox, Safari и т. Д. Позволяют сценарию продолжаться.Если вы возвращаете ошибку, вы можете захотеть, чтобы она возвратила успех со значением ошибки.

...