すべてのAJAXリクエストに「フック」して(送信されようとしているとき、またはイベントが発生したときに)、アクションを実行できるかどうかを知りたいです。この時点では、ページ上に他のサードパーティのスクリプトがあると想定しています。これらのいくつかはjQueryを使用するかもしれませんが、他は使用しません。これは可能ですか?
fetch()
現在のブラウザーで新しいAPI から行われたAjax呼び出しには適用されません。
すべてのAJAXリクエストに「フック」して(送信されようとしているとき、またはイベントが発生したときに)、アクションを実行できるかどうかを知りたいです。この時点では、ページ上に他のサードパーティのスクリプトがあると想定しています。これらのいくつかはjQueryを使用するかもしれませんが、他は使用しません。これは可能ですか?
fetch()
現在のブラウザーで新しいAPI から行われたAjax呼び出しには適用されません。
回答:
avivの回答に触発され、私は少し調査しましたが、これが私が思いついたものです。スクリプト内のコメント
のとおり、それがそれほど有用であるかどうかはわかりません。もちろん、ネイティブの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グローバルではなく、多分任意のサードパーティの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);
};
})();
ここでaddEventListener APIを使用して何ができるかについてのいくつかのドキュメント:
(これはIE8以下では機能しないことに注意してください)
this.status
ます。この場合200
、リクエストがOKの場合はサーバーのステータスを返し、要素が見つからなかった場合は404、500などを返します。ただし、コードは完全に機能します。
"load"
イベントは、成功した場合に呼ばれています。結果を気にしない場合(クエリが終了しただけ)、"loadend"
イベントを使用できます
あなたはjqueryのを言及しているので、私はjqueryの申し出を知っ.ajaxSetup()
セットのようなイベントのトリガーを含めグローバルなAjaxのオプションという方法をsuccess
、error
とbeforeSend
あなたが探しているもののように聞こえるものです- 。
$.ajaxSetup({
beforeSend: function() {
//do stuff before request fires
}
});
もちろん、このソリューションを使用しようとするすべてのページでjQueryの可用性を確認する必要があります。
それをするトリックがあります。
すべてのスクリプトを実行する前に、元のXHMHttpReuqestオブジェクトを取得して、別の変数に保存します。次に、元のXMLHttpRequestをオーバーライドし、すべての呼び出しを独自のオブジェクトを介してそれにリダイレクトします。
擬似コード:
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の回答に加えて、XHR呼び出しをインターセプトするiframeにコードを挿入する必要があり、上記の回答を使用しました。しかし、私は変えなければなりませんでした
XMLHttpRequest.prototype.send = function(){
に:
XMLHttpRequest.prototype.send = function(body)
そして私は変えなければなりませんでした
oldSend.apply(this, arguments);
に:
oldSend.call(this, body);
これは、IE8ドキュメントモードの IE9で機能させるために必要でした。この変更を行わなかった場合、コンポーネントフレームワーク(Visual WebGUI)によって生成された一部のコールバックが機能しませんでした。これらのリンクの詳細:
これらの変更がなければ、AJAXポストバックは終了しませんでした。