企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
# 其它补充 ## 动态注入或执行JS 虽然在`background`和`popup`中无法直接访问页面DOM,但是可以通过`chrome.tabs.executeScript`来执行脚本,从而实现访问web页面的DOM(注意,这种方式也不能直接访问页面JS)。 示例`manifest.json`配置: ``` <pre class="calibre10">``` <span class="token3">{</span> <span class="token2">"name"</span><span class="token3">:</span> <span class="token2">"动态JS注入演示"</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span> <span class="token2">"permissions"</span><span class="token3">:</span> <span class="token3">[</span> <span class="token2">"tabs"</span><span class="token3">,</span> <span class="token2">"http://*/*"</span><span class="token3">,</span> <span class="token2">"https://*/*"</span> <span class="token3">]</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span> <span class="token3">}</span> ``` ``` JS: ``` <pre class="calibre10">``` <span class="token">// 动态执行JS代码</span> chrome<span class="token3">.</span>tabs<span class="token3">.</span><span class="token4">executeScript</span><span class="token3">(</span>tabId<span class="token3">,</span> <span class="token3">{</span>code<span class="token3">:</span> <span class="token2">'document.body.style.backgroundColor="red"'</span><span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 动态执行JS文件</span> chrome<span class="token3">.</span>tabs<span class="token3">.</span><span class="token4">executeScript</span><span class="token3">(</span>tabId<span class="token3">,</span> <span class="token3">{</span>file<span class="token3">:</span> <span class="token2">'some-script.js'</span><span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## 动态注入CSS 示例`manifest.json`配置: ``` <pre class="calibre10">``` <span class="token3">{</span> <span class="token2">"name"</span><span class="token3">:</span> <span class="token2">"动态CSS注入演示"</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span> <span class="token2">"permissions"</span><span class="token3">:</span> <span class="token3">[</span> <span class="token2">"tabs"</span><span class="token3">,</span> <span class="token2">"http://*/*"</span><span class="token3">,</span> <span class="token2">"https://*/*"</span> <span class="token3">]</span><span class="token3">,</span> <span class="token3">.</span><span class="token3">.</span><span class="token3">.</span> <span class="token3">}</span> ``` ``` JS代码: ``` <pre class="calibre10">``` <span class="token">// 动态执行CSS代码,TODO,这里有待验证</span> chrome<span class="token3">.</span>tabs<span class="token3">.</span><span class="token4">insertCSS</span><span class="token3">(</span>tabId<span class="token3">,</span> <span class="token3">{</span>code<span class="token3">:</span> <span class="token2">'xxx'</span><span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 动态执行CSS文件</span> chrome<span class="token3">.</span>tabs<span class="token3">.</span><span class="token4">insertCSS</span><span class="token3">(</span>tabId<span class="token3">,</span> <span class="token3">{</span>file<span class="token3">:</span> <span class="token2">'some-style.css'</span><span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## 获取当前窗口ID ``` <pre class="calibre10">``` chrome<span class="token3">.</span>windows<span class="token3">.</span><span class="token4">getCurrent</span><span class="token3">(</span><span class="token5">function</span><span class="token3">(</span>currentWindow<span class="token3">)</span> <span class="token3">{</span> console<span class="token3">.</span><span class="token4">log</span><span class="token3">(</span><span class="token2">'当前窗口ID:'</span> <span class="token1">+</span> currentWindow<span class="token3">.</span>id<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## 获取当前标签页ID 一般有2种方法: ``` <pre class="calibre10">``` <span class="token">// 获取当前选项卡ID</span> <span class="token5">function</span> <span class="token4">getCurrentTabId</span><span class="token3">(</span>callback<span class="token3">)</span> <span class="token3">{</span> chrome<span class="token3">.</span>tabs<span class="token3">.</span><span class="token4">query</span><span class="token3">(</span><span class="token3">{</span>active<span class="token3">:</span> <span class="token6">true</span><span class="token3">,</span> currentWindow<span class="token3">:</span> <span class="token6">true</span><span class="token3">}</span><span class="token3">,</span> <span class="token5">function</span><span class="token3">(</span>tabs<span class="token3">)</span> <span class="token3">{</span> <span class="token5">if</span><span class="token3">(</span>callback<span class="token3">)</span> <span class="token4">callback</span><span class="token3">(</span>tabs<span class="token3">.</span>length <span class="token1">?</span> tabs<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">.</span>id<span class="token3">:</span> <span class="token5">null</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> ``` ``` 获取当前选项卡id的另一种方法,大部分时候都类似,只有少部分时候会不一样(例如当窗口最小化时) ``` <pre class="calibre10">``` <span class="token">// 获取当前选项卡ID</span> <span class="token5">function</span> <span class="token4">getCurrentTabId2</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> chrome<span class="token3">.</span>windows<span class="token3">.</span><span class="token4">getCurrent</span><span class="token3">(</span><span class="token5">function</span><span class="token3">(</span>currentWindow<span class="token3">)</span> <span class="token3">{</span> chrome<span class="token3">.</span>tabs<span class="token3">.</span><span class="token4">query</span><span class="token3">(</span><span class="token3">{</span>active<span class="token3">:</span> <span class="token6">true</span><span class="token3">,</span> windowId<span class="token3">:</span> currentWindow<span class="token3">.</span>id<span class="token3">}</span><span class="token3">,</span> <span class="token5">function</span><span class="token3">(</span>tabs<span class="token3">)</span> <span class="token3">{</span> <span class="token5">if</span><span class="token3">(</span>callback<span class="token3">)</span> <span class="token4">callback</span><span class="token3">(</span>tabs<span class="token3">.</span>length <span class="token1">?</span> tabs<span class="token3">[</span><span class="token6">0</span><span class="token3">]</span><span class="token3">.</span>id<span class="token3">:</span> <span class="token5">null</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> ``` ``` ## 本地存储 本地存储建议用`chrome.storage`而不是普通的`localStorage`,区别有好几点,个人认为最重要的2点区别是: - `chrome.storage`是针对插件全局的,即使你在`background`中保存的数据,在`content-script`也能获取到; - `chrome.storage.sync`可以跟随当前登录用户自动同步,这台电脑修改的设置会自动同步到其它电脑,很方便,如果没有登录或者未联网则先保存到本地,等登录了再同步至网络; 需要声明`storage`权限,有`chrome.storage.sync`和`chrome.storage.local`2种方式可供选择,使用示例如下: ``` <pre class="calibre10">``` <span class="token">// 读取数据,第一个参数是指定要读取的key以及设置默认值</span> chrome<span class="token3">.</span>storage<span class="token3">.</span>sync<span class="token3">.</span><span class="token4">get</span><span class="token3">(</span><span class="token3">{</span>color<span class="token3">:</span> <span class="token2">'red'</span><span class="token3">,</span> age<span class="token3">:</span> <span class="token6">18</span><span class="token3">}</span><span class="token3">,</span> <span class="token5">function</span><span class="token3">(</span>items<span class="token3">)</span> <span class="token3">{</span> console<span class="token3">.</span><span class="token4">log</span><span class="token3">(</span>items<span class="token3">.</span>color<span class="token3">,</span> items<span class="token3">.</span>age<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// 保存数据</span> chrome<span class="token3">.</span>storage<span class="token3">.</span>sync<span class="token3">.</span><span class="token4">set</span><span class="token3">(</span><span class="token3">{</span>color<span class="token3">:</span> <span class="token2">'blue'</span><span class="token3">}</span><span class="token3">,</span> <span class="token5">function</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> console<span class="token3">.</span><span class="token4">log</span><span class="token3">(</span><span class="token2">'保存成功!'</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## webRequest 通过webRequest系列API可以对HTTP请求进行任性地修改、定制,这里通过`beforeRequest`来简单演示一下它的冰山一角: ``` <pre class="calibre10">``` <span class="token">//manifest.json</span> <span class="token3">{</span> <span class="token">// 权限申请</span> <span class="token2">"permissions"</span><span class="token3">:</span> <span class="token3">[</span> <span class="token2">"webRequest"</span><span class="token3">,</span> <span class="token">// web请求</span> <span class="token2">"webRequestBlocking"</span><span class="token3">,</span> <span class="token">// 阻塞式web请求</span> <span class="token2">"storage"</span><span class="token3">,</span> <span class="token">// 插件本地存储</span> <span class="token2">"http://*/*"</span><span class="token3">,</span> <span class="token">// 可以通过executeScript或者insertCSS访问的网站</span> <span class="token2">"https://*/*"</span> <span class="token">// 可以通过executeScript或者insertCSS访问的网站</span> <span class="token3">]</span><span class="token3">,</span> <span class="token3">}</span> <span class="token">// background.js</span> <span class="token">// 是否显示图片</span> var showImage<span class="token3">;</span> chrome<span class="token3">.</span>storage<span class="token3">.</span>sync<span class="token3">.</span><span class="token4">get</span><span class="token3">(</span><span class="token3">{</span>showImage<span class="token3">:</span> <span class="token6">true</span><span class="token3">}</span><span class="token3">,</span> <span class="token5">function</span><span class="token3">(</span>items<span class="token3">)</span> <span class="token3">{</span> showImage <span class="token1">=</span> items<span class="token3">.</span>showImage<span class="token3">;</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token">// web请求监听,最后一个参数表示阻塞式,需单独声明权限:webRequestBlocking</span> chrome<span class="token3">.</span>webRequest<span class="token3">.</span>onBeforeRequest<span class="token3">.</span><span class="token4">addListener</span><span class="token3">(</span>details <span class="token1">=</span><span class="token1">></span> <span class="token3">{</span> <span class="token">// cancel 表示取消本次请求</span> <span class="token5">if</span><span class="token3">(</span><span class="token1">!</span>showImage <span class="token1">&&</span> details<span class="token3">.</span>type <span class="token1">==</span> <span class="token2">'image'</span><span class="token3">)</span> <span class="token5">return</span> <span class="token3">{</span>cancel<span class="token3">:</span> <span class="token6">true</span><span class="token3">}</span><span class="token3">;</span> <span class="token">// 简单的音视频检测</span> <span class="token">// 大部分网站视频的type并不是media,且视频做了防下载处理,所以这里仅仅是为了演示效果,无实际意义</span> <span class="token5">if</span><span class="token3">(</span>details<span class="token3">.</span>type <span class="token1">==</span> <span class="token2">'media'</span><span class="token3">)</span> <span class="token3">{</span> chrome<span class="token3">.</span>notifications<span class="token3">.</span><span class="token4">create</span><span class="token3">(</span><span class="token5">null</span><span class="token3">,</span> <span class="token3">{</span> type<span class="token3">:</span> <span class="token2">'basic'</span><span class="token3">,</span> iconUrl<span class="token3">:</span> <span class="token2">'img/icon.png'</span><span class="token3">,</span> title<span class="token3">:</span> <span class="token2">'检测到音视频'</span><span class="token3">,</span> message<span class="token3">:</span> <span class="token2">'音视频地址:'</span> <span class="token1">+</span> details<span class="token3">.</span>url<span class="token3">,</span> <span class="token3">}</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span><span class="token3">,</span> <span class="token3">{</span>urls<span class="token3">:</span> <span class="token3">[</span><span class="token2">"<all_urls>"</span><span class="token3">]</span><span class="token3">}</span><span class="token3">,</span> <span class="token3">[</span><span class="token2">"blocking"</span><span class="token3">]</span><span class="token3">)</span><span class="token3">;</span> ``` ``` ## 国际化 插件根目录新建一个名为`_locales`的文件夹,再在下面新建一些语言的文件夹,如`en`、`zh_CN`、`zh_TW`,然后再在每个文件夹放入一个`messages.json`,同时必须在清单文件中设置`default_locale`。 `_locales\en\messages.json`内容: ``` <pre class="calibre10">``` <span class="token3">{</span> <span class="token2">"pluginDesc"</span><span class="token3">:</span> <span class="token3">{</span><span class="token2">"message"</span><span class="token3">:</span> <span class="token2">"A simple chrome extension demo"</span><span class="token3">}</span><span class="token3">,</span> <span class="token2">"helloWorld"</span><span class="token3">:</span> <span class="token3">{</span><span class="token2">"message"</span><span class="token3">:</span> <span class="token2">"Hello World!"</span><span class="token3">}</span> <span class="token3">}</span> ``` ``` `_locales\zh_CN\messages.json`内容: ``` <pre class="calibre10">``` <span class="token3">{</span> <span class="token2">"pluginDesc"</span><span class="token3">:</span> <span class="token3">{</span><span class="token2">"message"</span><span class="token3">:</span> <span class="token2">"一个简单的Chrome插件demo"</span><span class="token3">}</span><span class="token3">,</span> <span class="token2">"helloWorld"</span><span class="token3">:</span> <span class="token3">{</span><span class="token2">"message"</span><span class="token3">:</span> <span class="token2">"你好啊,世界!"</span><span class="token3">}</span> <span class="token3">}</span> ``` ``` 在`manifest.json`和`CSS`文件中通过`__MSG_messagename__`引入,如: ``` <pre class="calibre10">``` <span class="token3">{</span> <span class="token2">"description"</span><span class="token3">:</span> <span class="token2">"__MSG_pluginDesc__"</span><span class="token3">,</span> <span class="token">// 默认语言</span> <span class="token2">"default_locale"</span><span class="token3">:</span> <span class="token2">"zh_CN"</span><span class="token3">,</span> <span class="token3">}</span> ``` ``` JS中则直接`chrome.i18n.getMessage("helloWorld")`。 测试时,通过给chrome建立一个不同的快捷方式`chrome.exe --lang=en`来切换语言,如:![](https://img.kancloud.cn/f9/a7/f9a78aa07e6921fb5c785daf46e61f23_422x281.png)