Я хотел бы знать, можно ли "подключить" к каждому запросу AJAX (как к отправке, так и по событиям) и выполнить действие. На этом этапе я предполагаю, что на странице есть другие сторонние скрипты. Некоторые из них могут использовать jQuery, а другие - нет. Возможно ли это?
Добавьте "крючок" ко всем запросам AJAX на странице
Ответ 1
Вдохновленный aviv answer, я немного разобрался, и это то, что я придумал.
Я не уверен, что все это полезное в соответствии с комментариями в script и, конечно, будет работать только для браузеров с использованием собственного объекта 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
});
Ответ 2
ПРИМЕЧАНИЕ. Принятый ответ не дает фактического ответа, поскольку его вызывают слишком рано.
Вы можете сделать это, что в общем случае будет перехватывать любой AJAX в глобальном масштабе и не портить никакие обратные вызовы и т.д., Которые, возможно, были назначены любыми сторонними библиотеками 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 здесь:
(Обратите внимание, это не работает <= IE8)
Ответ 3
Поскольку вы упоминаете jquery, я знаю, что jquery предлагает метод .ajaxSetup()
, который устанавливает глобальные параметры ajax, которые включают триггеры событий, такие как success
, error
и beforeSend
- это то, что похоже на то, что вы ищете для.
$.ajaxSetup({
beforeSend: function() {
//do stuff before request fires
}
});
конечно, вам нужно будет проверить доступность jQuery на любой странице, на которую вы пытаетесь использовать это решение.
Ответ 4
Есть трюк, чтобы сделать это.
Прежде чем запускать все сценарии, возьмите исходный объект XHMHttpReuqest и сохраните его в другом var. Затем переопределите исходный XMLHttpRequest и направьте все вызовы к нему через свой собственный объект.
Код Psuedo:
var savd = XMLHttpRequest;
XMLHttpRequest.prototype = function() {
this.init = function() {
}; // your code
etc' etc'
};
Ответ 5
Я нашел хорошую библиотеку в Github, которая хорошо выполняет эту работу, вы должны включить ее перед любыми другими js файлами
https://github.com/jpillora/xhook
вот пример, который добавляет HTTP-заголовок к любому входящему ответу
xhook.after(function(request, response) {
response.headers['Foo'] = 'Bar';
});
Ответ 6
Используя ответ "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 );
}
});
Ответ 7
В дополнение к 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 не завершались.
Ответ 8
JQuery...
<script>
$(document).ajaxSuccess(
function(event, xhr, settings){
alert(xhr.responseText);
}
);
</script>
Ответ 9
Ajax-hook - это lib с открытым исходным кодом для привязки глобального объекта 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])
}
})