モンキーパッチXMLHttpRequest
を適用するには、AJAXリクエストが一般的にどのように構築されるかを知る必要があります。
- コンストラクターの呼び出し
- リクエストの準備(
setRequestHeader()
、open()
)
- リクエストの送信(
.send
)。
汎用パッチ
(function(xhr) {
function banana(xhrInstance) { // Example
console.log('Monkey RS: ' + xhrInstance.readyState);
}
// Capture request before any network activity occurs:
var send = xhr.send;
xhr.send = function(data) {
var rsc = this.onreadystatechange;
if (rsc) {
// "onreadystatechange" exists. Monkey-patch it
this.onreadystatechange = function() {
banana(this);
return rsc.apply(this, arguments);
};
}
return send.apply(this, arguments);
};
})(XMLHttpRequest.prototype);
以前は、ハンドラーonreadystatechange
に割り当てられていると想定していました。簡単にするために、などの他のイベントonreadystatechange
のコードは含めませんでした。また、を使用して追加されたイベントは考慮していません。onload
addEventListener
以前のパッチはすべてのリクエストに対して実行されます。しかし、パッチを特定のリクエストのみに制限したい場合はどうでしょうか。特定のURLまたは非同期フラグと特定のリクエスト本文を持つリクエスト?
条件付きモンキーパッチ
POST
例:リクエスト本文に「TEST」が含まれているすべてのリクエストをインターセプトする
(function(xhr) {
function banana(xhrInstance) { // Example
console.log('Monkey RS: ' + xhrInstance.readyState);
}
//
var open = xhr.open;
xhr.open = function(method, url, async) {
// Test if method is POST
if (/^POST$/i.test(method)) {
var send = this.send;
this.send = function(data) {
// Test if request body contains "TEST"
if (typeof data === 'string' && data.indexOf('TEST') >= 0) {
var rsc = this.onreadystatechange;
if (rsc) {
// Apply monkey-patch
this.onreadystatechange = function() {
banana(this);
return rsc.apply(this, arguments);
};
}
}
return send.apply(this, arguments);
};
}
return open.apply(this, arguments);
};
})(XMLHttpRequest.prototype);
使用される主な手法は、...を使用した透過的な書き換えです。
var original = xhr.method;
xhr.method = function(){
/*...*/;
return original.apply(this, arguments);
};
私の例は非常に基本的なものであり、あなたの正確な希望に合わせて拡張することができます。ただし、それはあなた次第です。