ajaxHooker
ajax劫持库,支持xhr和fetch劫持。
今日安装
1
总安装量
47,452
创建日期
2022-09-24T13:28:02+00:00
更新日期
6 个月前
用户评分
10.0
// @require https://scriptcat.org/lib/637/1.4.3/ajaxHooker.js
论坛帖子
v1.4.3@require库

一个ajax劫持库,支持xhr和fetch劫持。注意:劫持发生的时机是库引入的时候,因此脚本应运行于document-start阶段,或至少于目标请求发生之前。不同版本的ajaxHooker同时生效时可能发生冲突,相同版本则不会引发错误,但修改效果可能相互覆盖。因1.4.0合并了不同脚本的ajaxHooker实例,与之前所有版本均不兼容,请尽量引用最新版本的库,以避免与其他脚本发生冲突

符合Greasy Fork规则的引用地址:

// @require https://scriptcat.org/lib/637/1.4.3/ajaxHooker.js#sha256=y1sWy1M/U5JP1tlAY5e80monDp27fF+GMRLsOiIrSUY=

ajaxHooker.hook

核心方法,通过一个回调函数进行劫持,每次请求发生时自动调用回调函数。可以将所有劫持放在同一回调函数中,也可以多次调用hook方法。示例:

ajaxHooker.hook(request => {
    console.log(request);
});

参数request是一个对象,其包含以下属性:
type
只读属性。一个字符串,表明请求类型是xhr还是fetch。
async
只读属性。异步请求为true,同步请求为false,异步特性无法作用于同步请求
url
method
请求的url和method,可以直接修改。
abort
是否取消请求,设置为true即可取消本次请求。
headers
请求头,可以直接修改。
data
请求携带的数据,可以直接修改。
response
响应内容,必须通过一个回调函数进行读取和修改。响应内容为一个对象,包含finalUrl、status、responseHeaders和被读取的响应数据,除响应数据可修改,其他属性是只读的。响应数据是哪个属性取决于哪个属性被读取,xhr可能的属性为responseresponseTextresponseXML,fetch可能的属性为arrayBufferblobformDatajsontext。修改对应属性即可影响读取结果,进而实现响应数据的修改。示例:

ajaxHooker.hook(request => {
    if (request.url === 'https://www.example.com/') {
        request.response = res => {
            console.log(res);
            res.responseText += 'test';
        };
    }
});

abort设置为true且response回调函数存在时,库将取消原请求并伪造一个成功响应,此时响应数据为空,直接对其赋值即可伪造响应结果。当你不需要原响应值时可使用此特性,以提高响应速度,减少不必要的请求。示例:

ajaxHooker.hook(request => {
    if (request.url === 'https://www.example.com/') {
        resquest.abort = true;
        request.response = res => {
            // res的finalUrl、status、responseHeaders均是伪造的,其他属性不存在
            console.log(res);
            res.responseText = 'test';
        };
    }
});

以下情况发生时,response回调函数将不会被执行:
1.请求未abort且发生失败时。
2.另一个脚本引入ajaxHooker且同时修改了response,则当前回调函数可能被覆盖(取决于执行顺序)。

异步特性

注意:异步特性无法作用于同步请求,但同步修改仍然有效。
你可以将以上所有可修改属性赋值为Promise,原请求将被阻塞直至Promise完成(若发生reject,数据将不会被修改),此特性可用于异步劫持。以下是一个异步修改响应数据的例子:

ajaxHooker.hook(request => {
    request.response = res => {
        const responseText = res.responseText; // 注意保存原数据
        res.responseText = new Promise(resolve => {
            setTimeout(() => {
                resolve(responseText + 'test');
            }, 3000);
        });
    };
});

也可以传入async回调函数以实现异步:

ajaxHooker.hook(async request => {
    request.data = await modifyData(request.data);
    request.response = async res => {
        res.responseText = await modifyResponse(res.responseText);
    };
});

ajaxHooker.filter

应于hook方法之前执行,此方法若尽早执行,有助于提升性能。
为hook方法设置过滤规则,只有符合规则的请求才会触发hook。过滤规则是一个对象数组,参考下例:

ajaxHooker.filter([
    {type: 'xhr', url: 'www.example.com', method: 'GET', async: true},
    {url: /^http/},
]);

type 可选,应是xhr或fetch。
url 可选,字符串或正则表达式,无需完全匹配。
method 可选,不区分大小写。
async 可选,布尔值。

ajaxHooker.protect

如果库劫持失败,可能是其他代码对xhr/fetch进行了二次劫持,protect方法会尝试阻止xhr和fetch被改写。应于document-start阶段尽早执行,部分网页下可能引发错误,谨慎使用。示例:

ajaxHooker.protect();

ajaxHooker.unhook

将xhr和fetch恢复至劫持前的状态,调用此方法后,hook方法不再生效。示例:

ajaxHooker.unhook();

更新日志

1.0.0
初始版本
1.0.1
修复应用于阿里云盘时的一个bug。
1.0.2
对响应头中的重复字段做合并处理。
1.1.0
1.headers和data属性现在可以直接读取修改了,回调函数方式已废弃,不向下兼容。
2.修复因原请求多次open和send引发的bug,减少多个ajaxHooker实例运行时的冲突现象。
1.1.1
处理多个ajaxHooker实例运行时的请求头冲突问题。
1.2.0
1.新增异步特性。
2.优化错误处理。
1.2.1
1.新增async函数支持。
2.优化xhr的劫持逻辑,以减少冲突概率。
1.2.2
1.新增filter方法。
2.修复已知问题。
1.2.3
1.修复filter方法的一个bug。
2.优化引用类型的响应数据读取问题。
1.2.4
1.减少对document-start的依赖。
2.现在可以正确处理URL类型的链接了。
1.3.0
1.重构部分代码,将xhr劫持改为Proxy方式。
2.修复已知问题。
1.3.1
修复了fetch请求的参数为Request类型时的一个bug。
1.3.2
处理异步劫持作用于同步请求时的bug,新增一个async参数。
1.3.3
修复一个小bug。
1.3.4
修复xhr请求可能意外变成同步的问题。
1.4.0
1.重构,减少重复代码(应该没有bug...吧)。
2.对不同脚本引入的ajaxHooker实例做合并处理,以减少冲突,提高性能。
3.现在允许通过abort参数在不发生请求的情况下伪造响应值。
4.修复已知问题。
1.4.1
修复特殊情况下有部分请求被跳过的问题。
1.4.2
修复了fetch请求的参数为Request类型时body类型不正确的bug。
1.4.3
1.修复特殊情况下有部分请求头丢失的问题。
2.xhr事件增加currentTarget劫持。
脚本评分
  • UU95 个月前

    真心好用

  • at20245 个月前

    太棒了

  • Gi_北风9 个月前

    太给力了 但是我的应用在 iframe 中 不能直接监听到

  • myaijarvis1 年前

    非常好用,就是油猴脚本无法提交:
    很抱歉,您提交的内容有点问题…
    Code 使用了一个未经批准的外部脚本:@require https://scriptcat.org/lib/637/1.3.3/aj

  • zhangxiucai2023-06-16T15:06:22+00:00

    试了一下,但是无法获取request.headers,获取的一直是空

  • Major2023-01-05T07:08:08+00:00

    太给力了,超级强大!!!!

  • 涛之雨2022-12-03T15:19:01+00:00

    超鸡好用,请删除后联系我,让我来发(bushi)

  • 王一之2022-12-03T15:13:07+00:00

    真的太好用了!方便快捷强大!