我想在发送body参数前捕获到请求并更改body参数,并在得到返回结果的时候拦截做一层处理,请问如何实现?
无法拦截。
JS 里内置的 API 除了 Proxy,压根也没提供 AOP(面向切面编程)的能力。
除非你复写它的原型链方法,但极不推荐此做法。因为如果你要做前端埋点或性能监控,你引入的那些库本身就会这么做(比如听云、OneAPM 之类的),你再做了二者就非常容易冲突,况且你复写的玩意儿大概率也不怎么健壮。
但你可以自己封装一层啊,封装层里你想怎么处理就怎么处理呗。需要 AJAX 的调用你自己封装的方法,而不是直接操作 XMLHttpRequest 对象。
P.S. 如果是开发 Chrome 插件那另有办法,但我估计你问的也不是怎么开发插件。
chrome中大部分api都是可以修改的,就比如你可以修改ajax的send方法,
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');
你也可以使用Proxy也可以做拦截,不过我还没试过。
既然说到拦截网络请求了,你也可以了解一下这个Service_Worker_API,虽然这个上手成本高,但是功能应该是最强到的,ajax,fetch,script脚本,css文件中的一些图片请求啥的都能拦截到也能做修改。
'use strict';
;(function () {
if (typeof window.XhrEvent === 'function') return false;
function XhrEvent (event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
XhrEvent.prototype = window.Event.prototype;
window.XhrEvent = XhrEvent;
})();
;(function () {
function xhrEventTrigger (event) {
// eslint-disable-next-line no-undef
var xhrEvent = new XhrEvent(event, { detail: this });
window.dispatchEvent(xhrEvent);
}
var oldXHR = window.XMLHttpRequest;
function newXHR (args) {
var realXHR = new oldXHR(args);
let oldSend = realXHR.send;
realXHR.send = function(data){
this.requestBody = data;
xhrEventTrigger.call(this, 'xhrSendStart');
oldSend.call(this, this.requestBody);
};
// 请求开始
realXHR.addEventListener('loadstart', function () { xhrEventTrigger.call(this, 'xhrLoadStart'); }, false);
// 请求进行中
realXHR.addEventListener('progress', function () { xhrEventTrigger.call(this, 'xhrProgress'); }, false);
realXHR.addEventListener('abort', function () { xhrEventTrigger.call(this, 'xhrAbort'); }, false);
// 请求错误
realXHR.addEventListener('error', function () { xhrEventTrigger.call(this, 'xhrError'); }, false);
// 请求中
realXHR.addEventListener('load', function () { xhrEventTrigger.call(this, 'xhrLoad'); }, false);
// 超时
realXHR.addEventListener('timeout', function () { xhrEventTrigger.call(this, 'xhrTimeout'); }, false);
// 请求完毕
realXHR.addEventListener('loadend', function () { xhrEventTrigger.call(this, 'xhrLoadEnd'); }, false);
// 请求状态改变
realXHR.addEventListener('readystatechange', function () { xhrEventTrigger.call(this, 'xhrReadyStateChange'); }, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
})();
window.addEventListener('xhrSendStart', function(e){
console.log(e.detail.requestBody);
e.detail.requestBody = '123321';
});
10 回答11k 阅读
6 回答2.9k 阅读
5 回答4.7k 阅读✓ 已解决
4 回答3k 阅读✓ 已解决
2 回答2.5k 阅读✓ 已解决
3 回答5k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
很巧,我今年恰好解决了同样的问题。 我的场景是在不污染现有前端库的前提下,记录所有异步请求的耗时。 列出代码,仅供参考,完全能解决你的问题。不要被这么长的代码吓到,最核心的部分只有几行,大部分是我用来计算耗时用的。