2010-01-04 3 views
4

У меня проблема, в основном с IE.Последовательные запросы Ajax без библиотеки jQuery/JS

Мне нужно иметь возможность обрабатывать n запросов один за другим. Но если я просто вызываю свою функцию ниже в IE цикла, то делает некоторые странные вещи (например, загружает только так много вызовов). Если я использую окно предупреждения, это доказывает, что функция получает все вызовы, и на удивление ЭТО РАБОТАЕТ!

Я полагаю, что для IE требуется больше времени, чем другие браузеры, и окно предупреждения делает именно это.

Вот мой код:

var Ajax = function(all) { 
    this.xhr = new XMLHTTPREQUEST(); // Function returns xhr object/ activeX 
    this.uri = function(queries) { // Takes an object and formats query string 
    var qs = "", i = 0, len = size(queries); 
    for (value in queries) { 
    qs += value + "=" + queries[value]; 
    if (++i <= len) { qs += "&"; } 
    } 
    return qs; 
    }; 
    xhr.onreadystatechange = function() { // called when content is ready 
    if (this.readyState === 4) { 
    if (this.status === 200) { 
    all.success(this.responseText, all.params); 
    } 
    this.abort(); 
    } 
    }; 
    this.post = function() { // POST 
    xhr.open("POST", all.where, true); 
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
    xhr.send(uri(all.queries)); 
    }; 
    this.get = function() { // GET 
    xhr.open("GET", all.where + "?" + uri(all.queries), true); 
    xhr.send(); 
    }; 
    if (this instanceof Ajax) { 
    return this.Ajax; 
    } else { 
    return new Ajax(all); 
    } 
}; 

Эта функция отлично работает для одного запроса, но как я могу заставить его работать, когда называются так много раз в течение цикла?

ответ

6

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

Похоже на то, что время ожидания вашего веб-сервиса отвечает на то, что ваши запросы на AJAX перекрываются, что, в свою очередь, превышает ограничение на 2 одновременных подключения.

Вы можете проверить эти статьи относительно этого ограничения:

Этого предел также предложил в HTTP спецификации: section 8.14 last paragraph, который вероятно, является основной причиной, по которой большинство браузеров ее навязывают.

Чтобы обойти эту проблему, вы можете рассмотреть возможность перезапуска вашего запроса AJAX ТОЛЬКО после успешного ответа от предыдущего вызова AJAX. Это предотвратит совпадение. Рассмотрим следующий пример:

function autoUpdate() { 
    var ajaxConnection = new Ext.data.Connection(); 

    ajaxConnection.request({ 
     method:   'GET', 
     url:   '/web-service/', 

     success: function (response) { 
      // Add your logic here for a successful AJAX response. 
      // ... 
      // ... 

      // Relaunch the autoUpdate() function in 100ms. (Could be less or more) 
      setTimeout(autoUpdate, 100); 
     } 
    } 
} 

В этом примере используется ExtJS, но вы можете очень легко использовать только XMLHttpRequest.

+0

Не только это, но когда вы начинаете второй запрос с использованием объекта SAME, предыдущий запрос прерывается. –

+0

Комментарий спецификации - это предложение, а не стандарт. Вы можете вступить в нее. –

+0

@ Без возврата Нет возврата: Спасибо ... Перефразировал мой ответ, чтобы указать на это как «предложение». –

0

Учитывая, что предел для одного домена является 2 параллельными соединениями в большинстве браузеров, он не дает никаких преимуществ по скорости, запуская более двух одновременных запросов. Запускайте 2 запроса и удаляйте и запускайте другой каждый раз, когда вы завершаете.

0

Я предлагаю изменить ваши запросы, чтобы у вас было всего несколько (4?) В любой момент времени. Вероятно, вы видите результат очередности очередей запросов и тайм-аутов до того, как ваш код сможет их обработать. Только гашь. У нас есть библиотека ajax, которая имеет встроенный дросселирование и очереди запросов, так что у нас есть только 4 выдающихся в любой момент времени и не вижу никаких проблем. Мы регулярно q лотов на страницу.

0

Ваш код выглядит так, как будто он составлен с использованием шаблона конструктора. Вы вызываете его с помощью нового оператора, например var foo = new Ajax(...) в своем кодовом коде? Или вы просто называете это прямо как var foo = Ajax(...)?

Если последнее, вы, вероятно, переписываете состояние при последующих звонках. Похоже, он предназначен для вызова для создания объекта, на который вызывается метод get/post.Это может быть вашей проблемой, если вы «вызываете ее в цикле», как вы говорите.

+0

Я использую новый оператор, и он не должен возвращать объект. Он не переопределяет, так как у всех других браузеров нет проблем. Синтаксис для вызова его будет выглядеть следующим образом: Ajax ({ где: 'somewhere.php', запросы: {ввод: "Привет"}, успех: функция (ответ) {Alert (ответ);}, params: []}). Get(); – Tom

+0

ОК. Тогда эта часть в порядке. Другая вещь, которая выглядит для меня тупой, - это определение переменных «xhr» и «uri». Вы определяете их в конструкторе как this.xhr и this.uri, но вы получаете доступ к ним позже как «xhr» и «uri». Я считаю, что они должны по умолчанию использовать глобальную область (или что-то другое). Не уверен, что подобные вещи уже определены в глобальном масштабе. Но если это хорошо работает в других браузерах, то вряд ли это будет проблемой семантики языка, поскольку IE в целом согласуется с другими браузерами на чистом JS. –

+0

«IE, как правило, довольно совместим с другими браузерами на чистом JS» ... this.i = «не уверен».; Я думал, что то же самое ... к сожалению, ничего не меняется. Вся проблема создания «реальных объектов» в JS и выполнения чего-то вроде «var that = this;» только для дизайна, все они делают почти то же самое. – Tom

Смежные вопросы