KangQingYu
Articles60
Tags21
Categories9
Proxyman rewrite注入vConsole

Proxyman rewrite注入vConsole

Proxyman rewrite如何使用

一 需求背景

信用卡tab预加载的时候,H5用于统计,所以需要Native调用H5的一段js方法:
"javascript:window._report_home_sw();"

iOS代码

1
    [self.webView.webView executeScript:@"window._report_home_sw();" handler:nil];

但是如何自测其生效了?需要注入 vConsole 脚本。通过查看H5变量的变化,确定是否收到。因此本文总结一下注入的步骤。

二 Charles 的rewrite配置

使用rewrite;选择response;
Rewrite Setting,Type选择Body。
Match 的Name空,Value填写<head>

Replace的Name空,Value如下(把<head>替换成如下值)

1
2
<head><script src="https://us.kqy.com/silver-bullet-img/2022-08-22/d8twU-vconsole.min.js"></script><script>var vConsole = new window.VConsole();</script>

这是公司部署的,其实是用的开源的vconsole。

1
https://unpkg.com/vconsole@3.15.1/dist/vconsole.min.js

三 Proxyman的配置

2022年5月的时候,购买了正版的Proxyman,39.5刀。与Charles相比,界面美观,内存占用也少。不过其没有rewrite功能,有更强大的JavaScript写脚本拦截。
如果用Proxyman操作,应该如何配置?

拦截脚本

最简单的配置

1
2
3
4
5
6
7
8
9
10
function onResponse(context, url, request, response) {
// 确保获取到的 response body 是文本格式 (HTML)
if (typeof response.body === 'string') {
var vconsoleScript = '<head><script src="https://kqy.com/silver-bullet-img/2022-08-22/d8twU-vconsole.min.js"></script><script>var vConsole = new window.VConsole();</script>';
// 将 <head> 替换为注入了脚本的内容
response.body = response.body.replace('<head>', vconsoleScript);
}
// 必须 return response 才能生效
return response;
}

但是不生效,即注入失败。因此要增加更多日志,用于判断为何注入失败。

精确判断请求的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function onResponse(context, url, request, response) {
console.log("__host__ SCRIPT TRIGGERED for URL: " + url);
const contentType = response.headers["Content-Type"] || "";
console.log("__type__ Content-Type: " + contentType);
// 只处理 HTML 页面 + 排除所有 /api/ 接口
if (contentType.includes("html") && !url.includes("/api/")) {
console.log("__ookk__ 检测到信用卡 H5 HTML 页面,开始注入 vConsole");
const injectedScript =
`<script src="https://kqy.com/silver-bullet-img/2022-08-22/d8twU-vconsole.min.js"></script>` +

`<script>var vConsole = new window.VConsole(); console.log('%c__ookk__ vConsole by Proxyman injected successfully!', 'color:#00ff00;font-size:16px');</script>`;

// 双重保险插入方式
let newBody = response.body.replace(/<\/head>/i, `${injectedScript}</head>`);
if (newBody === response.body) {
newBody = response.body.replace(/<head(\s[^>]*)?>/i, `<head$1>${injectedScript}`);
}
response.body = newBody;
console.log("__ookk__ 注入完成!新 body 长度: " + response.body.length);
} else {
console.log("__xxxxx__ 跳过(非 HTML 或 API 请求)");
}
return response;
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[18:22:50.876]: onResponse() is executed with Flow ID = 428
__host__ SCRIPT TRIGGERED for URL: https://kqy.com/b?sig=9c1f780999&h5_country=CN&lang=en-US&oid=YRR6z+T9ScSO8Y5dA
__type__ Content-Type: text/html; charset=UTF-8
__ookk__ 检测到信用卡 H5 HTML 页面,开始注入 vConsole
__ookk__ 注入完成!新 body 长度: 5835
18:22:50.883 onResponse() 已执行!
==========================
[18:22:52.218]: onResponse() is executed with Flow ID = 437
__host__ SCRIPT TRIGGERED for URL: https://s.dkqy.com/b/api/home/p?wsgsig=dsWfg%2F
__type__ Content-Type: application/json; charset=utf-8
__xxxxx__ 跳过(非 HTML 或 API 请求)
18:22:52.228 onResponse() 已执行!
==========================
[18:23:03.043]: onResponse() is executed with Flow ID = 475
__host__ SCRIPT TRIGGERED for URL: https://kqy.com/b/api/marketing/resource/queryOldApplyCardPage?wsgsig=dg9C%2F
__type__ Content-Type: application/json; charset=utf-8
__xxxxx__ 跳过(非 HTML 或 API 请求)

结果分析

text/html才是需要注入的请求;而application/json是API请求,过滤即可。

为何现金贷的接口,可以看到text/html,而信用卡没有呢?原来是打开了离线包。。。
关闭离线包之后,即可看到vConsole注入成功。

通过如下H5打印的变量可以确认调用成功

1
window._tab_click_flag = true
Author:KangQingYu
Link:http://example.com/2024/08/31/20240831Proxyman%20rewrite%E6%B3%A8%E5%85%A5vConsole/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×