1 前言
大家好,我是心锁,一枚23届准毕业生。
近期在做一个Chrome浏览器截图插件,功能是从浏览器截图并发送图片到企微,便于在远程办公环境下快速从浏览器发送图片进行showCase(目前未真正使用上,原因是截图时html2canvas有错位)
在开发浏览器插件时,有时候会遇到并不需要全屏截图的情况。比如,截图的时候忽略侧边栏只截图右侧的内容区。
所以在这个简单的需求下,我尝试通过允许用户自定义hook来实现
2 解决方案
我们要完成hook,本质上就是两种方法。
一种是动态代码注入(文件注入),一种是eval执行字符串
2.1 已知限制
开始之前,我们首先先获取一些(踩坑后明白的)已知限制:
- Chrome v3版本全面禁止eval, new Function,不管在
background
,inject
还是popup
中都无法通过任何手段开启 - Chrome v3版本全面禁止通过
script
标签加载外部源文件 - Chrome目前上的的插件仅支持v3,v2已经禁上架
那么在此基础上,我们能评估出哪些方案呢?
2.2 方案评估
2.3.1 unsafe-wasm-eval【❌】
经过chrome文档的查阅,发现在v3版本中允许对wasm文件做动态导入的操作
...
但是,WebAssembly的难度一下子击中我的心巴
...
不必多说,且往下看
2.3.2 动态注入chrome.tabs.executeScript【❌】
在查阅API文档时发现,chrome支持程序注入,可以胜任动态注入脚本
代码语言:javascript复制chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ['content-script.js']
});
});
那么我们现在需要考虑的就是能否生成文件并注入。
这就需要两个条件:
- 可以生成文件,即
File
对象存在 - 可以将文件转换成地址用于注入
对于前者是没有问题的
但是很遗憾,对于将文件转换成地址用于注入常用的APIURL.createObjectURL
是不支持的
2.3.3 在inject里做URL注入呢?【❌】
结合2.3.2,我们可以获得文件内容~
既然background不支持获得URL,那么我们在inject中跑行不行呢?
确实,我们可以拿到URL
传递URL到background之后再插入到content中
很遗憾还是不行,会直接找不到文件
而另一个方案是在content中注入script,这是实践内容,答案是不行。