cio*_*Pep 5 javascript ajax jquery
我试图覆盖ajaxsend事件的成功函数,但它不起作用的是代码:
$(document).ajaxSend(function(event,xhr,options){
console.log('ajaxSend');
var tempSuccess = options.success;
options.success = function(data, textStatus, jqXHR){
console.log('start');
tempSuccess(data, textStatus, jqXHR);
console.log('end');
}; xhr.success = options.success;});
Run Code Online (Sandbox Code Playgroud)
在AJAX上我确实在控制台中看到了'ajax',但是在成功的时候我看不到开始和结束的调试信息.
我做错了什么?
你想要完成的是无法完成的ajaxSend.问题是ajaxSend显然使用原始xhr和options对象的副本,因此修改不会产生任何影响.您可以使用以下代码轻松测试:
$(document).ajaxSend(function(event, xhr, options){
delete options.success;
console.log(options.success); // undefined
});
$.ajax({
url: "test.html",
success: function() { console.log("this will be printed nevertheless"); }
});
Run Code Online (Sandbox Code Playgroud)
所以你不能ajaxSend用来覆盖成功的回调.相反,你将不得不"破解"jQuery的AJAX功能:
// closure to prevent global access to this stuff
(function(){
// creates a new callback function that also executes the original callback
var SuccessCallback = function(origCallback){
return function(data, textStatus, jqXHR) {
console.log("start");
if (typeof origCallback === "function") {
origCallback(data, textStatus, jqXHR);
}
console.log("end");
};
};
// store the original AJAX function in a variable before overwriting it
var jqAjax = $.ajax;
$.ajax = function(settings){
// override the callback function, then execute the original AJAX function
settings.success = new SuccessCallback(settings.success);
jqAjax(settings);
};
})();
Run Code Online (Sandbox Code Playgroud)
现在您可以$.ajax像往常一样使用:
$.ajax({
url: "test.html",
success: function() {
console.log("will be printed between 'start' and 'end'");
}
});
Run Code Online (Sandbox Code Playgroud)
据我所知,任何jQuery的AJAX函数(如$.get()或.load())都在内部使用$.ajax,所以这应该适用于通过jQuery完成的每个AJAX请求(我还没有测试过这个......).
XMLHttpRequest.prototype.请注意,以下内容在IE中不起作用,而ActiveXObject不是使用XMLHttpRequest.
(function(){
// overwrite the "send" method, but keep the original implementation in a variable
var origSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data){
// check if onreadystatechange property is set (which is used for callbacks)
if (typeof this.onreadystatechange === "function") {
// overwrite callback function
var origOnreadystatechange = this.onreadystatechange;
this.onreadystatechange = function(){
if (this.readyState === 4) {
console.log("start");
}
origOnreadystatechange();
if (this.readyState === 4) {
console.log("end");
}
};
}
// execute the original "send" method
origSend.call(this, data);
};
})();
Run Code Online (Sandbox Code Playgroud)
用法(就像通常的XMLHttpRequest一样):
var xhr = new XMLHttpRequest();
xhr.open("POST", "test.html", true);
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
console.log("will be printed between 'start' and 'end'");
}
};
xhr.send();
Run Code Online (Sandbox Code Playgroud)
小智 -1
您可以使用闭包来完成您所需要的:
function closure(handler) {
return function(ev, xhr, options) {
console.log("start");
handler(ev, xhr, options);
console.log("stop");
}
}
$(document).ajaxSend(closure(function(ev, xhr, options) {
console.log("hello");
}));
Run Code Online (Sandbox Code Playgroud)