游客发表
浏览器地址栏旁边那个小图标,修改点一下,请求请求头就变了——这套操作,头插我每天要重复几十次。修改开发调试时改个Referer,请求测试环境伪造个Token,头插或者想看看某个接口到底返回了什么,修改都得靠它。请求市面上现成的头插修改请求头插件不少,但用着总隔靴搔痒。修改要么界面繁琐,请求要么只能改全局规则,头插要么连个基本的修改导出功能都没有。后来干脆自己写了一个,请求前前后后踩了不少坑,头插倒是摸清了这类工具的门道。
核心逻辑其实就一句话:拦截浏览器发出的所有网络请求,在它们到达服务器之前,把头部字段替换成你想要的。
但这句话背后藏着个关键问题——浏览器扩展的API权限是分层的。普通的content script根本碰不到网络层,你得用chrome.webRequest或declarativeNetRequest。前者是命令式,能拿到完整请求对象,随意增删改;后者是声明式,得提前把规则写成JSON,浏览器自己匹配执行。我一开始用的webRequest,简单粗暴,但有个致命伤——它需要"webRequestBlocking"权限,Chrome商店审核时会重点盯这个,稍有不慎就被标记为"侵犯隐私"。
后来换了declarativeNetRequest,规则全写在静态JSON里,反而更安全。但副作用是,它只能在请求头里改字符串,没法动态计算。比如你想把某个时间戳参数加进去,就没辙了。这时候得配合service worker,用chrome.declarativeNetRequest.updateDynamicRules动态注册规则,勉强能实现。说实话,这API设计得反人类,规则数组每改一次就得全量覆盖,性能开销大不说,调试时还得手动刷新扩展。
最烦人的是CORS预检请求。你以为改了请求头就万事大吉,结果浏览器先发一个OPTIONS探路,服务器一看头部不对,直接拒绝。这时候插件里写的规则根本没生效——因为预检请求是浏览器自己发的,你的扩展根本拦不到。解决办法只有一个:在规则里把Access-Control-Request-Headers也一并改掉,让它和实际请求保持一致。这个坑我踩了整整两天,最后翻Chromium源码才搞明白。
另一个容易被忽略的是缓存。改了请求头,但浏览器缓存了旧响应,你看到的还是老数据。必须同时给请求加上Cache-Control: no-cache,或者干脆禁用缓存。但这又会拖慢正常开发速度,所以我的插件里加了个开关,只在需要时强制刷新。说起来简单,实现时得区分主框架请求和子资源请求,还得处理重定向链——每次跳转都可能生成新的请求头,规则得跟着变。
现在这个插件已经成了我工作流的一部分。快捷键Ctrl+Shift+U呼出面板,左边是当前页面所有请求的列表,点击任意一条就能看到原始请求头,右侧编辑框直接改,改完按回车立即重发。没有花哨的UI,也没有规则模板,一切手动控制。有人可能觉得这样效率低,但对我来说,可视化地看到每个请求的实际内容,比盲目套用规则可靠得多。
写插件的过程,本质上是在跟浏览器的安全机制博弈。你越深入,越能感受到那些API设计者的顾虑——他们既要给开发者灵活性,又要防止恶意滥用。所以每个权限背后都有一堆限制条件。但正是这些限制,逼着你更精确地理解HTTP协议本身。现在再看那些动不动就崩溃的调试工具,我反而觉得,自己动手写一个,比什么都强。
友情链接