Surge 中文使用教程
2026-08-01发表于
JavaScript一、速览:Surge 是个什么样的项目
入门
Surge 是一个基于 JavaScript 的轻量级网络调试与请求转发工具,核心思路是拦截 HTTP/HTTPS 请求,按规则修改请求头、参数或响应内容,再转发到目标服务器。它常用于接口联调、Mock 数据、绕过前端签名校验、抓包分析等场景。
这个项目的定位很明确:不追求做全功能的代理软件,而是提供一个可编程的请求处理管道,让你用 JavaScript 脚本控制每一个请求的走向。相比 Charles 或 Fiddler 这类图形化抓包工具,Surge 更贴近「写代码处理请求」的工作流。
如果你经常写爬虫、调试前后端联调问题,或者需要快速给某个接口造数据,Surge 能省下不少重复劳动。它的代码量不大,结构清晰,也适合想学习 HTTP 拦截原理的开发者阅读源码。
注意:这个项目与 iOS 上的同名网络工具 Surge(Surge for iOS/macOS)没有关系,仓库地址是
Choler/Surge,不要混淆。
二、安装与启动
入门
Surge 依赖 Node.js 环境,建议使用 12 及以上版本。获取项目后直接安装依赖即可运行:
git clone https://github.com/Choler/Surge.git
cd Surge
npm install
启动服务默认监听 127.0.0.1:8000,执行:
npm start
看到控制台输出 Surge proxy server is running on port 8000 说明启动成功。此时将终端或应用的 HTTP 代理指向 127.0.0.1:8000,请求就会进入 Surge 的处理管道。
项目没有提供配置文件,所有行为都通过脚本文件控制。默认情况下,Surge 读取项目根目录下的 rules.js 作为处理逻辑入口。
三、核心用法:写一条请求处理规则
入门
Surge 的工作方式非常直接:你导出一个函数,函数接收请求对象,返回修改后的请求对象或响应对象。来看一个最小示例:
// rules.js
module.exports = (req) => {
// 给所有请求添加一个自定义头
req.headers['X-Custom-Header'] = 'hello-surge';
return req;
};
保存后重启服务,所有经过代理的请求都会带上这个头。如果想让某个接口直接返回假数据,可以返回一个响应对象:
module.exports = (req) => {
if (req.url.includes('/api/user')) {
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'mock-user', age: 18 })
};
}
return req;
};
返回 req 表示放行请求;返回一个带 statusCode 和 body 的对象则直接构造响应,不再访问真实服务器。这是 Surge 最核心的两个分支逻辑。
请求对象上常用的字段包括 method、url、headers、body,响应对象则支持 statusCode、headers、body。理解这几个字段就能覆盖大部分使用场景。
四、配置与定制:按域名分流、修改响应体
进阶 · 推荐细读
实际使用中,你通常只想拦截部分请求,而不是全部。Surge 支持在规则函数内做条件判断,实现按域名、路径或请求方法分流:
module.exports = (req) => {
// 只处理 API 请求
if (!req.url.startsWith('/api/')) return req;
// 对 POST 请求单独处理
if (req.method === 'POST') {
req.headers['X-Request-Source'] = 'surge-proxy';
}
// 修改请求体中的某个字段
if (req.body && req.body.userId) {
req.body.userId = '999999';
}
return req;
};
修改响应体是另一个高频需求。Surge 允许你在规则函数中返回一个 transform 函数,用于在拿到真实响应后做改写:
module.exports = (req) => {
if (req.url === '/api/list') {
return (res) => {
const data = JSON.parse(res.body);
data.items = data.items.filter(item => item.visible !== false);
res.body = JSON.stringify(data);
return res;
};
}
return req;
};
注意这里返回的不是响应对象,而是一个接收 res 并返回 res 的函数。这种「先放行、后改写」的模式很适合做数据清洗或字段脱敏。
提示:请求体
req.body只有在 Content-Type 为application/json或application/x-www-form-urlencoded时才会被自动解析为对象,其他格式(如二进制)保持原始字符串。
五、踩坑:常见问题与规避方法
进阶 · 推荐细读
HTTPS 请求需要额外处理。 Surge 默认只能拦截明文 HTTP 流量。对于 HTTPS 请求,需要设置环境变量 NODE_TLS_REJECT_UNAUTHORIZED=0 来跳过证书校验,但这会带来安全风险,建议只在本地开发环境使用:
NODE_TLS_REJECT_UNAUTHORIZED=0 npm start
规则函数必须同步返回。 Surge 的处理管道是同步的,不支持在规则函数内使用 async/await。如果需要异步操作(比如查数据库),建议提前把数据加载到内存中,或者在函数外部做预取。
修改请求体后 Content-Length 不会自动更新。 如果你手动改了 req.body,但长度变了,目标服务器可能报 411 或解析错误。建议在修改后手动更新:
req.headers['Content-Length'] = Buffer.byteLength(req.body);
代理只对显式设置了代理的客户端生效。 浏览器默认不会走系统代理,需要手动配置或使用 SwitchyOmega 等插件。curl 测试时加上 -x 参数:
curl -x http://127.0.0.1:8000 http://example.com
六、进阶:动态规则与多环境切换
深入 · 老手可选
Surge 的规则文件只是一个普通 Node 模块,这意味你可以利用 JavaScript 的全部能力来构建规则。比如根据环境变量切换不同配置:
const env = process.env.SURGE_ENV || 'dev';
const mockData = {
dev: { name: 'dev-user' },
test: { name: 'test-user' }
};
module.exports = (req) => {
if (req.url.includes('/api/user') && env !== 'prod') {
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(mockData[env])
};
}
return req;
};
启动时指定环境:
SURGE_ENV=test npm start
另一个实用技巧是把规则拆分成多个模块,按需加载。比如把 Mock 规则放到 mocks/ 目录,用 fs.readdirSync 动态加载:
const fs = require('fs');
const path = require('path');
const mocks = {};
fs.readdirSync(path.join(__dirname, 'mocks')).forEach(file => {
if (file.endsWith('.js')) {
const name = path.basename(file, '.js');
mocks[name] = require(`./mocks/${file}`);
}
});
module.exports = (req) => {
for (const mock of Object.values(mocks)) {
const result = mock(req);
if (result) return result;
}
return req;
};
每个 mock 文件只负责一个接口的拦截逻辑,互不干扰,维护起来比单文件堆叠清晰得多。
七、判断建议:这个项目适合你吗
入门
Surge 适合以下场景:
- 接口联调时快速造 Mock 数据,不用等后端就绪
- 爬虫开发中绕过简单的签名校验,修改请求头或参数
- 学习 HTTP 代理实现原理,代码量小、逻辑直白,适合通读
如果你的需求是图形化抓包、断点调试、流量录制回放,Surge 并不合适——这些功能它都没有。同样,如果你需要处理 HTTPS 双向认证或复杂的代理链,Surge 的同步模型会限制你。
项目目前维护频率不高,Star 数也不多,但核心功能稳定,作为开发辅助工具完全够用。建议先跑通最小示例,确认它能满足你的需求,再决定是否深度使用。
项目信息
| 项目 | 值 |
|---|---|
| 仓库 | Choler/Surge |
| 语言 | JavaScript |
| Star | 292 |
| Fork | 65 |
| 主页 | 无 |
参考链接
80
48
1
1037
文章目录
评论