14

我正在尝试构建一个脚本,该脚本将充当本机XMLHttpRequest对象的代理/包装器,使我能够拦截它、修改 responseText 并返回到原始的 onreadystatechange 事件。

上下文是,如果应用程序尝试接收的数据已在本地存储中可用,则中止XMLHttpRequest并将本地存储的数据传递回应用程序成功/失败回调方法。假设我无法控制应用程序现有的 AJAX 回调方法。

我最初尝试过以下想法..

var send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data){
   //Do some stuff in here to modify the responseText
   send.call(this, data);
};

但正如我现在所建立的,responseText 是只读的。

然后我尝试退后一步,编写我自己的完整本机代理到XMLHttpRequest,最终编写我自己的本机方法版本。类似于这里讨论的...

http://www.ilinsky.com/articles/XMLHttpRequest/#implementation-wrapping

但是它很快就变得混乱了,并且仍然很难将修改后的数据返回到原始onReadyStateChange方法中。

有什么建议么?这甚至可能吗?

4

3 回答 3

7

//
// firefox, ie8+ 
//
var accessor = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'responseText');

Object.defineProperty(XMLHttpRequest.prototype, 'responseText', {
	get: function() {
		console.log('get responseText');
		return accessor.get.call(this);
	},
	set: function(str) {
		console.log('set responseText: %s', str);
		//return accessor.set.call(this, str);
	},
	configurable: true
});


//
// chrome, safari (accessor == null)
//
var rawOpen = XMLHttpRequest.prototype.open;

XMLHttpRequest.prototype.open = function() {
	if (!this._hooked) {
		this._hooked = true;
		setupHook(this);
	}
	rawOpen.apply(this, arguments);
}

function setupHook(xhr) {
	function getter() {
		console.log('get responseText');

		delete xhr.responseText;
		var ret = xhr.responseText;
		setup();
		return ret;
	}

	function setter(str) {
		console.log('set responseText: %s', str);
	}

	function setup() {
		Object.defineProperty(xhr, 'responseText', {
			get: getter,
			set: setter,
			configurable: true
		});
	}
	setup();
}

于 2015-02-14T06:43:40.483 回答
1

以下脚本在通过 XMLHttpRequest.prototype.send 发送之前完美拦截数据

<script>
(function(send) { 

        XMLHttpRequest.prototype.send = function(data) { 

            this.addEventListener('readystatechange', function() { 

            }, false); 

            console.log(data); 
            alert(data); 

        }; 

})(XMLHttpRequest.prototype.send);
</script>
于 2014-05-08T10:44:06.423 回答
0

您的后退是一种矫枉过正:您可以在 XMLHttpRequest 上添加自己的 getter:(有关属性的更多信息)

Object.defineProperty(XMLHttpRequest.prototype,"myResponse",{
  get: function() {
    return this.responseText+"my update"; // anything you want
  }
});

用法:

var xhr = new XMLHttpRequest();
...
console.log(xhr.myResponse); // xhr.responseText+"my update"

关于您可能运行的现代浏览器的注意事项xhr.onload(请参阅XMLHttpRequest2 提示

于 2013-06-06T10:23:44.943 回答