javascript - 非法调用 addEventListener.call(xhr, "readystatechange", callback)
问题描述
在我的应用程序中,我们想要捕获 AJAX 请求和响应数据。为此,我们创建了围绕 XmlHttpReqeust 对象的包装器,如下示例代码所示。这工作正常,直到 angular(和许多其他 JS 框架)开始使用 addEventListener.call(xhr, "readystatechange", callback)。在这里,xhr 是我们包装类的对象。它在浏览器上引发“非法调用”错误。
这是我们的包装器(代理)实现的示例代码 -
(function (window) {
var actualXHR = XMLHttpRequest;
var XhrProxy = function () {
this.xhr = new actualXHR();
this.IsPostMethod;
this.Method;
this.Async;
this.User;
this.Pass;
this.Url;
this.sendData;
function delegate(prop) {
Object.defineProperty(this, prop, {
get: function () {
return this.xhr[prop];
},
set: function (value) {
if (this.Async == undefined || this.Async || prop != "responseType") {
this.xhr[prop] = value;
}
}
});
}
delegate.call(this, 'timeout');
delegate.call(this, 'responseType');
delegate.call(this, 'withCredentials');
delegate.call(this, 'onerror');
delegate.call(this, 'onabort');
delegate.call(this, 'onloadstart');
delegate.call(this, 'onloadend');
delegate.call(this, 'onprogress');
delegate.call(this, 'readystatechange');
};
XhrProxy.prototype.open = function (method, url, async, user, pass) {
var ctx = this;
this.Method = method;
this.Async = async;
this.User = user;
this.Pass = pass;
this.Url = url;
this.xhr.open.apply(this.xhr, arguments);
this.xhr.onload = function (evt) {
// Log response
if (ctx.onload)
ctx.onload(evt);
};
this.xhr.onreadystatechange = function (evt) {
if (ctx.onreadystatechange) {
return ctx.onreadystatechange(evt);
}
};
};
XhrProxy.prototype.addEventListener = function (event, fn) {
return this.xhr.addEventListener.apply(this.xhr, arguments);
};
XhrProxy.prototype.send = function (data) {
this.sendData = data;
// Log sendData
return this.xhr.send.apply(this.xhr, arguments);
};
XhrProxy.prototype.abort = function () {
return this.xhr.abort.apply(this.xhr, arguments);
};
XhrProxy.prototype.getAllResponseHeaders = function () {
return this.xhr.getAllResponseHeaders.apply(this.xhr, arguments);
};
XhrProxy.prototype.getResponseHeader = function (header) {
return this.xhr.getResponseHeader.apply(this.xhr, arguments);
};
XhrProxy.prototype.setRequestHeader = function (header, value) {
// Log headers
return this.xhr.setRequestHeader.apply(this.xhr, arguments);
};
XhrProxy.prototype.overrideMimeType = function (mimetype) {
return this.xhr.overrideMimeType.apply(this.xhr, arguments);
};
XhrProxy.interceptors = [];
XhrProxy.addInterceptor = function (fn) {
this.interceptors.push(fn);
};
window.XMLHttpRequest = XhrProxy;
})(window);
当任何消费者代码订阅readystatechange
使用 addEventListener.call(xhr, "readystatechange", callback) 时,我们会在浏览器上收到“非法调用”错误。
这是获取“非法调用”的示例代码:
function callback() {
// handle callback
}
var xhr = new XmlHttpRequest(); // it's object of wrapper class (XhrProxy)
xhr.open("GET", "someurl");
addEventListener.call(xhr, "readystatechange", callback); // <- this throws 'Illegal Invocation'
任何建议如何处理这种情况?
解决方案
推荐阅读
- python - 如何通过元素的总和来限制 np 数组
- python - 使用 groupby 从特定行中减去值
- javascript - vue中组件销毁的问题
- google-cloud-functions - Google Cloud Functions - 如何设置功能(交易机器人)
- tableau-api - 删除特定选定值的菜单选项?
- c++ - 在特定位置向字符串添加空格
- python - Python C 扩展优化速度 (Linux)
- sql - 将新的时间戳值插入到 kamailio 中的 acc 表
- python - python - 如何使用boto3使用python仅将更改的文件从一个S3 Bucket复制到另一个S3 Bucket?
- c# - 如何使用 puppeteer-sharp touchStart 和 touchEnd 和 touch move