jQuery Ajax, перезаписать обработчик onreadystatechange - PullRequest
4 голосов
/ 22 июля 2010

Я недавно дурачился с некоторыми методами опроса ajax. Однако кажется, что я не могу переписать обработчик onreadystatechange из объекта XMLHttpRequest в FireFox (3.6.7).

Отслеживая проблему, почему FF выдает исключение при попытке доступа к onreadystatechange, я понял, что это зависит от того, был вызван метод send() или нет.

Другими словами, вот пример (обычный js, пока нет jQuery), который работает:

(Это довольно просто для демонстрации)

var myxhr = new XMLHttpRequest();
myxhr.open("GET", "/my/index.php");
myxhr.onreadystatechange = function(){
    console.log('ready state changed');
};
console.log("onreadystatechange function: ", myxhr.onreadystatechange);
myxhr.send(null);

Это работает, лучше сказать, что здесь можно получить доступ к myxhr.onreadystatechange. Если я переключаю последние две строки кода, FF выдает исключение, в основном говоря мне, что мне не разрешен доступ к этому объекту.

myxhr.send(null);
console.log("onreadystatechange function: ", myxhr.onreadystatechange);

Не удается.

Так где же моя настоящая проблема?

Хорошо, я хочу использовать jQuery $.ajax(). Но если я попытаюсь перезаписать метод onreadystatechange объекта XHR, который был возвращен из $.ajax(), я получу то же исключение FireFox.

Хорошо, я уже выяснил, почему это происходит, поэтому я подумал: а что насчет свойства beforeSend $.ajax()? Итак, я в основном попробовал это:

var myxhr = $.ajax({
   url:        "/my/index.php",
   type:       "GET",
   dataType:   "text",
   data:        {
       foo:    "1"
   },
   beforeSend: function(xhr){
       var readystatehook = xhr.onreadystatechange;

       xhr.onreadystatechange = function(){
           readystatehook.apply(this, []);
           console.log('fired');
       };
   },
   success:    function(data){
       console.log(data);
   },
   error:      function(xhr, textStatus, error){
       console.log(xhr.statusText, textStatus, error);
   }
});

Угадайте, что FireFox выдает исключение. Так что же вы делаете сейчас? Вы копаетесь в исходном коде jQuery, как я. Но это принесло больше вопросов, чем ответов на самом деле. Похоже, что beforeSend() действительно вызывается до выполнения xhr.send(). Поэтому мне интересно, почему же FireFox не позволяет перезаписывать обработчик на этом этапе.

Заключение

Невозможно создать custom readystatechange handler с помощью jQuery / Firefox?

Ответы [ 3 ]

2 голосов
/ 11 марта 2011

Я согласен с Maz здесь, вы все еще можете воспользоваться обработкой запросов и созданием объекта, а также нет необходимости исправлять jquery для этого

, однако, если вы не возражаете против исправления jquery, вы можете добавить этистрок

        // The readystate 2
        } else if ( !requestDone && xhr && xhr.readyState === 2 && isTimeout !== 'timeout' && s.state2) {
            s.state2.call( s.context, data, status, xhr );
        // The readystate 3
        } else if ( !requestDone && xhr && xhr.readyState === 3 && isTimeout !== 'timeout' && s.state3) {
            s.state3.call( s.context, data, status, xhr );

перед этой строкой: (jQuery v 1.4.4) или просто найдите readyState === 4 в источнике

        // The transfer is complete and the data is available, or the request timed out
        } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {

, теперь вы можете использовать $.Снова ajax и установите обработчик для state2 и state3 следующим образом:

$.ajax({
    url: 'http://www.stackoverflow.com',
    cache: false,
    success:function(){console.log('success');},
    error: function (){console.log('error');},
    complete: function (){console.log('complete');},
    state2: function (context,data,status,xhr) {console.log('state2');},
    state3: function (context,data,status,xhr) {console.log('state3');}
});

он не ведет себя точно так же, как другие обработчики, например, returngin false не будет ничего делать, но вы все равно можете обработать объект xhr и прервать егоway

плохо посмотрим, смогу ли я представить это для включения в источник позже в этот день, кто знает, что они могут принять это

1 голос
/ 22 июля 2010

Если вы хотите большой уровень настройки, вы можете просто получить объект XMLHttpRequest и управлять им самостоятельно.

var x=new $.ajaxSettings.xhr();
x.onreadystatechange=function(){ ... }
...
0 голосов
/ 19 февраля 2011

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

$.ajax({
type: "POST",
url: "Test.ashx",
data: { "command": "test" },
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "json",
beforeSend: function (request, settings) {
    $(request).bind("readystatechange", function (e) { alert("changed " + e.target.readyState); });
}});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...