0x01 遇到的问题
i. WebRequest & Ajax
先放上
request
的生命周期图Chrome 官方处于安全考虑对于插件修改 User-Agent 的操作很敏感,但也在
WebRequest
API中提供了修改方法及示例代码The following example illustrates how to delete the User-Agent header from all requests:
chrome.webRequest.onBeforeSendHeaders.addListener( function(details) { for (var i = 0; i < details.requestHeaders.length; ++i) { if (details.requestHeaders[i].name === 'User-Agent') { details.requestHeaders.splice(i, 1); break; } } return {requestHeaders: details.requestHeaders}; }, {urls: ["<all_urls>"]}, ["blocking", "requestHeaders"]);
有个坑就是
WebRequest
修改User-Agent
是不支持同步
的JS
原生的xhr
以及jquery
的$.ajax
,貌似这个BUG没有修复过。个人测试大致如下,总体来说就是异步 UA 可被更改
注:
$.ajax
在未设置type时等同于$.get
HTTP 请求 | xhr |
xhr (async=false) |
$.ajax |
$.ajax (async=false) |
$.get |
$.post |
---|---|---|---|---|---|---|
WebRequest能否修改UA | ✔ | ✘ | ✔ | ✘ | ✔ | ✔ |
同时在上面的链接中提到了
declarativeWebRequest
可能支持修改,然而被官方文档一句描述所终结Note: this API is currently on hold, without concrete plans to move to stable.
外加一句可用性的补刀
Availability: Beta and Dev channels only.
所以如何取舍就成了问题,当然也可使用
async/await
调整执行顺序
ii. content-script vs injected-script
从易用性、消息通信方面选择,肯定都是 CS > IS,放上他人总结的互相通信概览
注:
-
表示不存在或者无意义,或者待验证。注:发现此表确认已过时,待补充
\ | injected-script | content-script | popup-js | background-js |
---|---|---|---|---|
injected-script | - | window.postMessage | - | - |
content-script | window.postMessage | - | chrome.runtime.sendMessage chrome.runtime.connect |
chrome.runtime.sendMessage chrome.runtime.connect |
popup-js | - | chrome.tabs.sendMessage chrome.tabs.connect |
- | chrome.extension.getBackgroundPage() |
background-js | - | chrome.tabs.sendMessage chrome.tabs.connect |
chrome.extension.getViews | - |
devtools-js | chrome.devtools.inspectedWindow.eval | - | chrome.runtime.sendMessage | chrome.runtime.sendMessage |
但是在使用中,如果页面中的一些 dom 节点是二次渲染的,CS 去获取节点时候,在
document_end
之后都只会返回为空,这时候就需要动态插入js,即injectd-script然后通信方向就成了
injected-script <<<>>> content-script <<<>>> background
,原本还想把结果放到 popup 里,那通信简直美如画
iii. content-css vs injected-css
这个其实没有什么可吐槽的,就是插入时需要小心控制,很容易影响全局,何况 CSS 还写不好 Orz
0x02 开发 fir.im 下载助手
fir.im 对于
android/ios
客户端下载逻辑有部分区分,android
是直链下载,但ios
需要通过同一步给予的链接并使用ios ua
访问一个install.xml
文件后获取最终下载链接。而由于
ajax
无法修改user-agent
,亦不想异步推送信息至injected-script
增加复杂度,所以将下载单独剥离出来。为了区分
android
直链下载还是ios
解析xml下载,由于下载文件需要跨域到https://pro-bd.fir.im
,ajax
会因CORS
策略导致访问失败,所以可以用ajax
的成功与否来进行简单区别。
项目地址
https://github.com/sari3l/Chrome-Extensions/tree/master/fir.im%20Downloader