Добавьте "крючок" ко всем запросам AJAX на странице
Я хотел бы знать, можно ли "зацепить" каждый запрос AJAX (либо по мере его отправки, либо по событиям) и выполнить действие. На данный момент я предполагаю, что есть и другие сторонние скрипты на странице. Некоторые из них могут использовать jQuery, а другие-нет. Это возможно?
9 ответов:
вдохновленный - Авива, Я сделал небольшое расследование, и это то, что я придумал.
Я не уверен, что это все, что полезно согласно комментариям в скрипте и конечно будет работать только для браузеров, использующих собственный объект XMLHttpRequest.
Я думаю, что это будет работать, если библиотеки javascript используются, поскольку они будут использовать собственный объект, если это возможно.function addXMLRequestCallback(callback){ var oldSend, i; if( XMLHttpRequest.callbacks ) { // we've already overridden send() so just add the callback XMLHttpRequest.callbacks.push( callback ); } else { // create a callback queue XMLHttpRequest.callbacks = [callback]; // store the native send() oldSend = XMLHttpRequest.prototype.send; // override the native send() XMLHttpRequest.prototype.send = function(){ // process the callback queue // the xhr instance is passed into each callback but seems pretty useless // you can't tell what its destination is or call abort() without an error // so only really good for logging that a request has happened // I could be wrong, I hope so... // EDIT: I suppose you could override the onreadystatechange handler though for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) { XMLHttpRequest.callbacks[i]( this ); } // call the native send() oldSend.apply(this, arguments); } } } // e.g. addXMLRequestCallback( function( xhr ) { console.log( xhr.responseText ); // (an empty string) }); addXMLRequestCallback( function( xhr ) { console.dir( xhr ); // have a look if there is anything useful here });
Если вам не нужно поддерживать любой Аякс глобально и не запороть любые обратные вызовы и т. д. это может быть назначено любыми сторонними библиотеками AJAX. Принятый ответ не дает фактического ответа, потому что он вызывается слишком рано.
(function() { var origOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function() { console.log('request started!'); this.addEventListener('load', function() { console.log('request completed!'); console.log(this.readyState); //will always be 4 (ajax is completed successfully) console.log(this.responseText); //whatever the response was }); origOpen.apply(this, arguments); }; })();еще несколько документов о том, что вы можете сделать здесь с помощью API addEventListener здесь:
поскольку вы упомянули jquery, я знаю, что jquery предлагает
.ajaxSetup()метод, который устанавливает глобальные параметры ajax, которые включают триггеры событий, такие какsuccess,errorиbeforeSend- что это звучит как то, что вы ищете.$.ajaxSetup({ beforeSend: function() { //do stuff before request fires } });конечно, вам нужно будет проверить доступность jQuery на любой странице, на которой вы пытаетесь использовать это решение.
есть трюк, чтобы сделать это.
перед запуском всех сценариев возьмите исходный объект XHMHttpReuqest и сохраните его в другом var. Затем переопределите исходный XMLHttpRequest и направьте все вызовы к нему через свой собственный объект.
код Psuedo:
var savd = XMLHttpRequest; XMLHttpRequest.prototype = function() { this.init = function() { }; // your code etc' etc' };
Я нашел хорошую библиотеку на Github, которая хорошо справляется с этой работой, вы должны включить ее перед любыми другими файлами js
https://github.com/jpillora/xhook
вот пример, который добавляет заголовок http к любому входящему ответу
xhook.after(function(request, response) { response.headers['Foo'] = 'Bar'; });
используя ответ "meouw" я предлагаю использовать следующее решение, если вы хотите увидеть результаты запроса
function addXMLRequestCallback(callback) { var oldSend, i; if( XMLHttpRequest.callbacks ) { // we've already overridden send() so just add the callback XMLHttpRequest.callbacks.push( callback ); } else { // create a callback queue XMLHttpRequest.callbacks = [callback]; // store the native send() oldSend = XMLHttpRequest.prototype.send; // override the native send() XMLHttpRequest.prototype.send = function() { // call the native send() oldSend.apply(this, arguments); this.onreadystatechange = function ( progress ) { for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) { XMLHttpRequest.callbacks[i]( progress ); } }; } } } addXMLRequestCallback( function( progress ) { if (typeof progress.srcElement.responseText != 'undefined' && progress.srcElement.responseText != '') { console.log( progress.srcElement.responseText.length ); } });
jquery...
<script> $(document).ajaxSuccess( function(event, xhr, settings){ alert(xhr.responseText); } ); </script>
в дополнение к ответу meouw мне пришлось ввести код в iframe, который перехватывает вызовы XHR, и использовал приведенный выше ответ. Однако, мне пришлось изменить
XMLHttpRequest.prototype.send = function(){To:
XMLHttpRequest.prototype.send = function(arguments)и мне пришлось изменить
oldSend.apply(this, arguments);To:
oldSend.call(this, arguments);Это было необходимо, чтобы заставить его работать в IE9 с режим документа IE8. Если это изменение не было сделано, некоторые обратные вызовы, созданные платформой компонентов (Visual WebGUI), не работали. Более подробная информация по этим ссылкам:
Ajax-hook - это библиотека с открытым исходным кодом для подключения глобального объекта XMLHttpRequest и изменения запроса и ответа Ajax по умолчанию . github:https://github.com/wendux/Ajax-hook , например:
hookAjax({ //hook callbacks onreadystatechange:function(xhr){ console.log("onreadystatechange called: %O",xhr) }, onload:function(xhr){ console.log("onload called: %O",xhr) }, //hook function open:function(arg,xhr){ console.log("open called: method:%s,url:%s,async:%s",arg[0],arg[1],arg[2]) } })
Comments