简单记一下,如何拦截 XHR 请求。
代码
let oldXHR = window.XMLHttpRequest;
//hook xhr
function newXHR() {
let realXHR = new oldXHR();
let oldSendFun = realXHR.send;
//修改 ajax 的 send 方法
realXHR.send = function (body) {
console.log("拦截到消息提",body)
oldSendFun.call(realXHR,body)
}
return realXHR;
}
window.XMLHttpRequest = newXHR;
//这是一个测试用例
let ajax = new XMLHttpRequest();
ajax.open('post', 'inser.php', true);
ajax.send('name=2');
还有很多更好的详细写法
;(function (w) {
// document.getElementById('textDesc').innerHTML='ES5 局部拦截 XHR 并添加请求头:'
w.rewriteXhr = {
// 随机生成 uuid
_setUUID: function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
tempXhrProto: function (){
this._originXhr = w.XMLHttpRequest.prototype
this._Originopen = this._originXhr.open
this._OriginSetRequestHeader = this._originXhr.setRequestHeader
},
overWrite: function () {
var _this = this
this._originXhr.open = function () {
// note open 才能获取到 url 等参数。
this._open_args = [...arguments];
// 可以根据 return 顾虑调不需要执行的 return
return _this._Originopen.apply(this, arguments);
}
// 拦截 setRequestHeader 方法
this._originXhr.setRequestHeader = function () {
var headerKey = arguments[0]
// note: 可使用 url 做过滤处理
// var url = this.open_args && this.open_args[1]
if (/^custom-trace-id$/.test(headerKey)) {
var args = arguments[1] && arguments[1].split(',')
var values = {
'custom-a': args[0],
'custom-b': args[1],
'custom-uuid': _this._setUUID()
}
Object.entries(values).forEach(([key, value])=>{
// note: 用箭头函数偷一下懒
this.setRequestHeader(key, value)
})
return _this._OriginSetRequestHeader.apply(this, arguments)
}
// note: 声明时已丢失上下文,必须要使用 apply、call
return _this._OriginSetRequestHeader.apply(this, arguments)
}
},
init: function () {
// 1. 存储原生的 xhr 原型
this.tempXhrProto()
// 2. 重写 xhr
this.overWrite()
}
}
w.rewriteXhr.init()
})(window)
// 复制、粘贴 可直接使用