1,简介
Ajax-hook可以自定义XMLHttpRequest中的方法和属性,覆盖全局的XMLHttpRequest对象。当网站使用Ajax请求渲染时,可以对其中的请求数据和响应数据进行任意修改和展示。
2,源码
!function (ob){
ob.hookAjax=function(funs){
window._ahrealxhr=window._ahrealxhr || XMLHttpRequest;
XMLHttpRequest=function(){
this.xhr=new window._ahrealxhr;
for (var attr in this.xhr){ //遍历XMLHttpRequest对象的所有属性并重构
var type="";
try{
type=typeof(this.xhr[attr])
}catch(e){}
if (type=="function"){
this[attr]=hookfun(attr);
}else{
//在对象 obj 上定义新的属性,或者修改对象 obj 中的属性,结果返回对象 obj。
//第一个参数 obj 是目标对象,第二个参数 prop 是属性键名,第三个参数是这个属性的描述符。
Object.defineProperty(this,attr,{
get:getFactory(attr),
set:setFactory(attr)
})
}
}
};
function getFactory(attr){
return function(){
return this.hasOwnProperty(attr+"_")?this[attr+'_']:this.xhr[attr];
}
}
function setFactory(attr){
return function(f){
var xhr=this.xhr;
var that=this;
if (attr.indexOf("on")!=0){
this[attr+"_"]=f;
return ;
}
if(funs[attr]){
xhr[attr]=function(){
funs[attr](that) || f.apply(xhr,arguments);
}
}else{
xhr[attr]=f;
}
}
}
function hookfun(fun){
return function(){
// 能将具有length属性的对象转成数组
var args=[].slice.call(arguments)
// 调用开发者自定义的方法
if(funs[fun] && funs[fun].call(this,args,this.xhr)){
return;
}
return this.xhr[fun].apply(this.xhr,args);
}
}
return window._ahrealxhr;
}
ob.unHookAjax=function(){
if(window._ahrealxhr){
XMLHttpRequest=window._ahrealxhr;
window._ahrealxhr=undefined;
}
}
}(window);
hookAjax({
onreadystatechange:function(xhr){
if(xhr.status == 200){
console.log("response--->",xhr.response)
}
return false;
},
open:function(arg){
var url=arg[1]
console.log("send url--->",arg[1])
},
send:function(arg){
console.log("send called",arg)
}
})
将浏览器window对象传入,并获取全局真实的XMLHttpRequest对象,同时对XMLHttpRequest对象中的API接口进行遍历,自定义重写这些方法和属性。
对XMLXMLHttpRequest对象重要方法进行重写。
1,open() :初始化一个请求
2,send(): 将请求发送至服务器
3,onreadystatechange():每当 ajax请求状态 改变时,onreadystatechange 函数就会被执行。
3,测试
1,首先打开 https://spa1.scrape.center/,将js注入浏览器中
2,点击下一页,浏览器发送ajax请求,截获请求,并输出。