请求脚本

Shadowrocket 的脚本功能(Scripting)允许用户使用 JavaScript 对 HTTP/HTTPS 请求和响应进行编程处理,实现自定义的网络行为修改,这是其高级功能之一,类似于 Surge 和 Quantumult X 的脚本系统。

脚本类型与触发时机

Shadowrocket 支持以下几种脚本类型:

类型 触发时机 用途
HTTP-Request 发送 HTTP 请求前 修改请求头、URL、Body,重定向
HTTP-Response 收到 HTTP 响应后 修改响应数据、解密、去广告
Network-changed 网络切换时 WiFi/蜂窝网络切换触发
Cron 定时执行 自动签到、定时任务

基本脚本结构

// 脚本元数据(Shadowrocket 会自动解析注释)
/*
[Script]
ScriptName = type=http-request,pattern=^https?://api\.example\.com/,script-path=local/script.js,requires-body=true
[MITM]
hostname = api.example.com
*/
// 脚本主体
const url = $request.url;
const headers = $request.headers;
// 修改逻辑...
$done({url: modifiedUrl, headers: headers});

核心 API 对象

$request 对象(请求阶段)

{
  url: "https://api.example.com/path",
  method: "GET",
  headers: {...},
  body: "raw body data"  // 需要 requires-body=true
}

$response 对象(响应阶段)

{
  status: 200,
  headers: {...},
  body: "response data"  // 需要 requires-body=true
}

常用方法

  • $done(obj):结束脚本并返回修改后的数据
  • $notify(title, subtitle, message):发送系统通知
  • $persistentStore.read/write(key):本地存储
  • $httpClient.get/post():发起新请求
  • $script.startTime:脚本开始时间

配置方式

方式 1:配置文件直接编写

在 Shadowrocket 配置文件的 [Script] 段添加:

[Script]Bilibili-PG = type=http-request,pattern=^https://app\.bilibili\.com/,script-path=bilibili.js,requires-body=false
# 响应脚本
Bilibili-AD = type=http-response,pattern=^https://app\.bilibili\.com/x/resource/show/tab,requires-body=true,script-path=bilibili-ad.js
[MITM]
hostname = app.bilibili.com

方式 2:使用模块(Module)

创建 .sgmodule 文件导入:

#!name=示例模块
#!desc=这是一个示例脚本模块
[Script]
HTTP-Request = type=http-request,pattern=^https?://example\.com/,script-path=https://raw.githubusercontent.com/.../script.js
[MITM]
hostname = %APPEND% example.com

实用示例

示例 1:修改 User-Agent

// ua-modify.js
const headers = $request.headers;
headers['User-Agent'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15';
$done({headers});

示例 2:JSON 数据修改(去广告)

// remove-ads.js
let body = JSON.parse($response.body);
// 假设广告数据在 data.ads 中
if (body.data && body.data.ads) {
  body.data.ads = [];
}
$done({body: JSON.stringify(body)});

示例 3:URL 重定向

// redirect.js
const url = $request.url.replace('old-domain.com', 'new-domain.com');
$done({url});

示例 4:定时签到脚本(Cron)

[Script]
CheckIn = type=cron,cronexp=0 9 * * *,script-path=checkin.js
// checkin.js
$httpClient.get('https://api.example.com/sign', (error, response, data) => {
  if (error) {
    $notify('签到失败', '', error);
  } else {
    $notify('签到成功', '', data);
  }
  $done();
});

调试与排错

  1. 查看日志:Shadowrocket → 设置 → 日志(Log)
  2. 脚本测试:使用 console.log() 输出变量,在日志中查看
  3. 语法检查:确保 JavaScript 语法正确,特别是 JSON 解析部分
  4. MITM 证书:修改 HTTPS 请求必须安装并信任证书

注意事项

  1. 性能影响:复杂脚本会增加延迟,避免在高频接口使用重型脚本
  2. 内存限制:iOS 对扩展内存有限制,避免处理过大的 Response Body(>10MB 可能崩溃)
  3. 同步/异步$httpClient 是异步的,注意 $done() 的调用时机
  4. 正则性能pattern 使用正则匹配,避免过于复杂的正则表达式

与 Surge/Quantumult X 的兼容性

Shadowrocket 脚本语法基本兼容 Surge 的脚本格式,但存在细微差异:

  • Shadowrocket 不支持 script-update-interval(脚本自动更新需手动)
  • 部分高级 API(如 $environment)可能缺失
  • 模块系统语法与 Surge 基本一致

建议:编写脚本时参考 Shadowrocket 官方文档或测试兼容性,复杂脚本建议使用 Surge 或 Quantumult X 的语法规范以确保可移植性。

您可以还会对下面的文章感兴趣: