前言
之前我们已经谈过了fetch劫持,但是由于那个代码相对较为复杂,cxxjackie提供了一个相对简单的方式,并未使用proxy劫持,我们这节课来分析一下。
let oldfetch = fetch;
function fuckfetch() {
return new Promise((resolve, reject) => {
oldfetch.apply(this, arguments).then(response => {
const oldJson = response.json;
response.json = function() {
return new Promise((resolve, reject) => {
oldJson.apply(this, arguments).then(result => {
result.hook = 'success';
resolve(result);
});
});
};
resolve(response);
});
});
}
window.fetch = fuckfetch;
oldfetch保存了原fetch的引用
这时候我们对window.fetch挂载成我们的劫持函数,fuckfetch
因为fetch需要返回一个promise,所以这里我们通过
return new Promise((resolve, reject) => {})
包裹了一下,并且在原fetch函数内调用,并获取返回内容,对其进行一些处理并resolve返回过去。
附注:函数一旦返回一个Promise,我们只考虑输出相同的结果即可,而无须考虑Promise内处理过程的一致性。
oldfetch.apply(this, arguments).then(response => {
const oldJson = response.json;
response.json = function() {
return new Promise((resolve, reject) => {
oldJson.apply(this, arguments).then(result => {
result.hook = 'success';
resolve(result);
});
});
};
resolve(response);
});
这里我们使用fetch的原函数,通过apply更改了this指针至自身,并且传入了参数。注意这点有一个需要注意的是,我们劫持函数的时候,由劫持函数调用原函数的过程中一定要使用call/apply进行修改this指针,来符合原来的调用过程。
在then后则是我们处理response的过程
const oldJson = response.json;
response.json = function() {
return new Promise((resolve, reject) => {
oldJson.apply(this, arguments).then(result => {
result.hook = 'success';
resolve(result);
});
});
};
这部分代码是针对某些特定的函数进行过滤,我们可以对网页进行分析以及调试,或去返回内容进行查看,来判断调用了哪些函数。
这里以json为例进行劫持
首先保存了原json的引用
然后修改json属性为一个劫持函数
由于json返回的是一个promise对象,所以我们这里也需要返回一个promise
在promise内依然是对其原json函数进行调用,并修改了this指向以及参数,最后对其结果进行一定的修改,然后通过resolve(result)进行返回。
那么这节课我们就了解到了一个相对较为轻量的fetch劫持方法!
结语
撒花~