警告
文末有修改版代码
xhr返回内容劫持是我在一个无聊日子搞出来的玩应,并没有一次应用于实践
可能对一些条件的判断存在问题,另外proxy会在频繁通信中降低性能!
理论存在更好的解决方法,在此仅提供一个思路作为参考
开始
具体代码可以参考https://bbs.tampermonkey.net.cn/thread-769-1-1.html
var oldxhr=window.XMLHttpRequest
function newobj(){}
首先声明一个变量获取xhr
然后保存,并且创建一个newobj的函数
window.XMLHttpRequest=函数
对window下的xhr进行劫持,劫持后创建的xhr都由我们负责创建
let tagetobk=new newobj();
tagetobk.oldxhr=new oldxhr();
对空newobk函数进行一个new创建出一个对象
并创建一个xhr挂载到对象上,方便使每次创建的xhr跟对象对应
let handle={
get: function(target, prop, receiver) {
if(prop==='oldxhr'){
return Reflect.get(target,prop);
}
if(typeof Reflect.get(target.oldxhr,prop)==='function')
{
if(Reflect.get(target.oldxhr,prop+'proxy')===undefined)
{
target.oldxhr[prop+'proxy']=new Proxy(Reflect.get(target.oldxhr,prop), {
apply: function(target, thisArg, argumentsList) {
debugger;
return Reflect.apply(target, thisArg.oldxhr, argumentsList);
}
}); }
return Reflect.get(target.oldxhr,prop+'proxy')
}
if(prop.indexOf('response')!==-1)
{
console.log('我们劫持成功了!',Reflect.get(target.oldxhr,prop))
return 'FFFFFFFFUCK'
}
return Reflect.get(target.oldxhr,prop);
},
set(target, prop, value) {
return Reflect.set(target.oldxhr, prop, value);
},
has(target, key) {
debugger;
return Reflect.has(target.oldxhr,key);
}
对这个空对象进行proxy处理,set的时候自动设置到对象下的oldxhr上
当获取属性的时候判断是否是oldxhr,如果是就返回oldxhr
如果不是则判断获取的是否是函数
并判断获取的属性名+proxy是否存在,如果存在则执行,如果不存在则创建一个
创建的函数也是一层proxy
通过proxy的apply函数修改this指针指向其自身的xhr
然后判断查询数据是否带有response,如果带有则我们获取返回数据并开始劫持
如果不带有则返回默认的数据
这样我们就可以在通过对xhr进行劫持的下对数据进行劫持和过滤了!
更新
// ==UserScript==
// @name XHR劫持返回内容例子
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://bbs.tampermonkey.net.cn/*
// @icon https://www.google.com/s2/favicons?domain=undefined.
// @grant none
// ==/UserScript==
var oldxhr=window.XMLHttpRequest
function newobj(){}
window.XMLHttpRequest=function(){
let tagetobk=new newobj();
tagetobk.oldxhr=new oldxhr();
let handle={
get: function(target, prop, receiver) {
if(prop==='oldxhr'){
return Reflect.get(target,prop);
}
if(typeof Reflect.get(target.oldxhr,prop)==='function')
{
if(Reflect.get(target.oldxhr,prop+'proxy')===undefined)
{
target.oldxhr[prop+'proxy']=(...funcargs)=> {
let result=target.oldxhr[prop].call(target.oldxhr,...funcargs)
console.log('函数劫持获取结果',result)
return result;
}
}
return Reflect.get(target.oldxhr,prop+'proxy')
}
if(prop.indexOf('response')!==-1)
{
console.log('属性劫持结果',Reflect.get(target.oldxhr,prop))
return Reflect.get(target.oldxhr,prop)
}
return Reflect.get(target.oldxhr,prop);
},
set(target, prop, value) {
return Reflect.set(target.oldxhr, prop, value);
},
has(target, key) {
debugger;
return Reflect.has(target.oldxhr,key);
}
}
let ret = new Proxy(tagetobk, handle);
return ret;
}
这里在cxxjackie的指导下进一步修改了代码