#Chrome扩展程序开发教程--04:脚本注入
- 引言
- 1、基本介绍
- 2、静态声明式注入
- 3、动态声明式注入
- 4、程序化注入
引言
本系列博客旨在带来最新的Chrome扩展程序开发入门教程。
1、基本介绍
Content scripts 是注入到网页中运行的 JavaScript 文件。它可以使用标准的 Document Object Model(DOM)对象来访问网页中内容并对其进行修改。由于安全等原因 content scripts 的运行环境和网页内容本身是隔离的,也就是说网页本身所创建对象和函数,在 content scripts 中是无法访问的,反之亦然。而且 content scripts 只能使用以下列出的 Chrome API:
- i18n
- storage
- runtime
- connect
- getManifest
- getURL
- id
- onConnect
- onMessage
- sendMessage
但可以通过与 service worker 进行通信来间接使用其它 Chrome API(第一章中有介绍)。
2、静态声明式注入
在 manifest.json 文件中声明哪些 content scripts 应该注入到哪些网页中,如下所示:
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.nytimes.com/*"],
"css": ["my-styles.css"],
"js": ["content-script.js"]
}
],
...
}
所有可用字段见下表:
name | Type | Description |
---|---|---|
matches | array of strings | 必须字段,指定 content scripts 将被注入到哪些页面。 |
exclude_matches | array of strings | 可选字段,指定不需要注入的页面。 |
all_frames | boolean | 可选字段,指定是否注入到目标页面中的所有 frame 中。 默认为 false,即只注入到目标页面的 top frame 中。 |
js | array of strings | 可选字段,指定要注入到匹配页面的 JS 文件。 默认在目标网页 DOM 被构建或显示前注入,注入顺序为在 list 中的顺序。 |
css | array of strings | 可选字段,指定要注入到匹配页面的 CSS 文件。 默认在目标网页 DOM 被构建或显示前注入,注入顺序为在 list 中的顺序。 |
run_at | RunAt | 可选字段,指定 content scripts 何时被注入到页面。 默认为 document_idle。其它可选:document_start、document_end。 |
match_about_blank | boolean | 可选字段,指定 content scripts 是否应该注入到 about:blank 标签页中。 默认为false。 |
match_origin_as_fallback | boolean | 可选字段,指定 content scripts 是否应该注入目标网页创建的所有 frame,即使该 frame 不满足 matches 中指定的规则。 |
include_globs | array of strings | 可选字段,指定需要匹配的 glob。 |
exclude_globs | array of strings | 可选字段,指定不需要匹配的glob |
world | ExecutionWorld | 可选字段,content scripts 执行环境。 默认为 ISOLATED。其它可选:MAIN |
3、动态声明式注入
允许开发者可以通过 Chrome API 动态添加、删除、修改或获取 content scripts 行为,如下所示:
chrome.scripting
.registerContentScripts([{
id: "session-script",
js: ["content.js"],
persistAcrossSessions: false,
matches: ["*://example.com/*"],
runAt: "document_start",
}])
.then(() => console.log("registration complete"))
.catch((err) => console.warn("unexpected error", err))
chrome.scripting
.updateContentScripts([{
id: "session-script",
excludeMatches: ["*://admin.example.com/*"],
}])
.then(() => console.log("registration updated"));
chrome.scripting
.getRegisteredContentScripts()
.then(scripts => console.log("registered content scripts", scripts));
chrome.scripting
.unregisterContentScripts({ ids: ["session-script"] })
.then(() => console.log("un-registration complete"));
4、程序化注入
程序化注入方式适用于那些需要响应某些事件或在某些特定场合下运行的 content scripts 。程序化注入需要在 manifest.json 中指定 host_permissions 或使用 activeTab 来临时指定当前页面,如下:
1.在 manifest.json 中指定 activeTab 来获取当前界面的访问权限。
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
2.在 background.js 中指定需要响应的事件。
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["content-script.js"]
});
});
3.在 content-script.js 中做出具体的响应。
document.body.style.backgroundColor = "orange";
当然, 如果任务比较简单,也可以直接在 background.js 中完成。
function injectedFunction(color) {
document.body.style.backgroundColor = color;
}
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target : {tabId : tab.id},
func : injectedFunction,
args : [ "orange" ],
});
});