Chrome 插件 V3 版本 Manifest.json 中的内容脚本(Content Scripts)解析

这篇具有很好参考价值的文章主要介绍了Chrome 插件 V3 版本 Manifest.json 中的内容脚本(Content Scripts)解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内容脚本(Content Scripts)

指定在用户打开某些网页时要使用的 JavaScriptCSS 文件。

内容脚本是在网页环境中运行的文件。通过使用标准文档对象模型 (DOM),开发者能够读取浏览器所访问网页的详情、更改这些网页,并将信息传递给其父级扩展程序。

一、内容脚本功能

内容脚本在声明扩展程序文件为可通过网络访问的资源后,便可访问扩展程序文件。他们可以直接访问以下扩展程序 API

  • dom
  • i18n
  • storage
  • runtime.connect()
  • runtime.getManifest()
  • runtime.getURL()
  • runtime.id
  • runtime.onConnect
  • runtime.onMessage
  • runtime.sendMessage()

内容脚本无法直接访问其他 API。但用户可以通过与扩展程序的其他部分交换消息来间接访问这些扩展程序。

二、隔离环境

隔离世界是一种私有执行环境,页面或其他扩展程序无法访问。这种隔离带来的实际结果是,扩展程序内容脚本中的 JavaScript 变量对托管页面或其他扩展程序的内容脚本不可见。此概念最初是在 Chrome 首次发布时引入的,用于隔离浏览器标签页。

不仅每个扩展程序都会在各自的独立世界中运行,内容脚本和网页也会在这方面运行。这意味着它们(网页、内容脚本和任何正在运行的扩展程序)都无法访问其他项的上下文和变量。

内容脚本位于一个独立的环境中,这使得内容脚本可以对其 JavaScript 环境进行更改,而不会与网页或其他扩展程序的内容脚本发生冲突。

1. 示例

插件在类似于以下示例的网页中运行。

webPage.html

<html>
  <button id="mybutton">click me</button>
  <script>
    var greeting = "hello, ";
    var button = document.getElementById("mybutton");
    button.person_name = "Bob";
    button.addEventListener(
        "click", () => alert(greeting + button.person_name + "."), false);
  </script>
</html>

该扩展程序可以使用注入脚本部分中所述的方法之一注入以下内容脚本。

content-script.js文章来源地址https://www.toymoban.com/news/detail-805739.html

var greeting = "hola, ";
var button = document.getElementById("mybutton");
button.person_name = "Roberto";
button.addEventListener("click", () => alert(greeting + button.person_name + "."), false);

进行此项更改后,用户点击按钮时,系统会按顺序显示两个提醒。

三、注入脚本(Inject scripts)

内容脚本可以静态声明、动态声明或以编程方式注入。

1. 使用静态声明进行注入

使用 manifest.json 中的静态内容脚本声明。

静态声明的脚本在清单中的 "content_scripts" 键下注册。可以包含 JavaScript 文件和/ CSS 文件。所有自动运行的内容脚本都必须指定匹配模式。

manifest.json

{
 "name": "My extension",
 "content_scripts": [
   {
     "matches": ["https://*.nytimes.com/*"],
     "css": ["my-styles.css"],
     "js": ["content-script.js"]
   }
 ],
}
名称 类型 说明
matches 字符串数组 string[] 必需。指定将此内容脚本注入到哪些网页。
css 字符串数组 string[] 可选。要注入到匹配页面的 CSS 文件列表。这些代码会按照它们在此数组中出现的顺序进行注入,然后为网页构建或显示任何 DOM
js 字符串数组 string[] 可选。要注入到匹配页面的 JavaScript 文件的列表。系统会按照文件在此数组中出现的顺序注入文件。此列表中的每个字符串都必须包含扩展程序根目录中某项资源的相对路径。前导斜杠(“/”)会自动剪除。
run_at RunAt 可选。指定应将脚本注入网页的时间。默认为 document_idle
match_about_blank 布尔值 boolean 可选。脚本是否应注入到 about:blank 帧中,其中父帧或起始帧与 matches 中声明的模式之一匹配。默认值为 false
match_origin_as_fallback 布尔值 boolean 可选。脚本是否应在由匹配的来源创建但其网址或来源可能与模式不直接匹配的帧中注入。其中包括采用不同架构的帧,例如 about:data:blob: 和 filesystem:
world ExecutionWorld 可选。要在其中执行脚本的 JavaScript 环境。默认值为 ISOLATED
1.1 RunAt
  • document_start
    • DOM 仍在加载。
  • document_end
    • 网页的资源仍在加载
  • document_idle
    • DOM 和资源已加载完毕。这是默认值。
1.2 ExecutionWorld
  • ISOLATED
    • 指定独立的世界,这是扩展程序独有的执行环境。
  • MAIN
    • 指定 DOM 的主环境,即与托管网页的 JavaScript 共享的执行环境。

2. 使用动态声明进行注入

如果内容脚本的匹配模式并不为人所知,或者内容脚本不应总是注入已知主机上,就需要使用动态进行注入。

内容脚本对象是使用 chrome.scripting 命名空间(而不是 manifest.json)中的方法在 Chrome 中注册的。

Scripting API 还允许扩展程序开发者执行以下操作:

  • 注册内容脚本。
  • 获取已注册内容脚本的列表。
  • 更新已注册内容脚本的列表。
  • 移除已注册的内容脚本。

动态声明可以包含 JavaScript 文件和或 CSS 文件。

service-worker.js

2.1. 注册
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))
2.2. 更新
chrome.scripting
  .updateContentScripts([{
    id: "session-script",
    excludeMatches: ["*://admin.example.com/*"],
  }])
  .then(() => console.log("registration updated"));
2.3. 获取
chrome.scripting
  .getRegisteredContentScripts()
  .then(scripts => console.log("registered content scripts", scripts));
2.4. 移除
chrome.scripting
  .unregisterContentScripts({ ids: ["session-script"] })
  .then(() => console.log("un-registration complete"));

3. 以编程方式注入

对于需要为了响应事件或在特定情况下运行的内容脚本,使用程序化注入。

如需以编程方式注入内容脚本,扩展程序需要对要尝试注入脚本的页面拥有主机权限。可以通过在扩展程序清单中请求这些权限来授予主机权限,也可以通过 activeTab 暂时授予主机权限。

3.1. 内容文件作为脚本进行注入

manifest.json

{
  "name": "My extension",
  "permissions": [
    "activeTab",
    "scripting"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Action Button"
  }
}

content-script.js

document.body.style.backgroundColor = "orange";

service-worker.js

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    files: ["content-script.js"]
  });
});
3.2. 注入函数正文,并将其作为内容脚本执行。

service-worker.js

function injectedFunction() {
  document.body.style.backgroundColor = "orange";
}

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target : {tabId : tab.id},
    func : injectedFunction,
  });
});
3.3 注入函数时,可以传递参数

service-worker.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" ],
  });
});

四、排除匹配项和 glob

如需自定义指定的网页匹配,请在声明式注册中添加以下字段

名称 类型 说明
exclude_matches 字符串数组 string[] 可选。不包括此内容脚本将被注入的网页。
include_globs 字符串数组 string[] 可选。在 matches 之后应用,以仅包含也与此 glob 匹配的网址。
exclude_globs 字符串数组 string[] 可选。在 matches 之后应用,以排除与此 glob 匹配的网址。

1. 排除/包含匹配

如果同时满足以下两个条件,内容脚本将会注入到网页中:

  • 其网址与任何 matches 格式和 include_globs 格式匹配。
  • 该网址也不符合 exclude_matches 或 exclude_globs 格式。由于 matches 属性是必需的,因此 exclude_matchesinclude_globs 和 exclude_globs 只能用于限制哪些页面会受到影响。
1.1. 示例

以下扩展程序会将内容脚本注入 https://www.nytimes.com/health,但不会注入 https://www.nytimes.com/business

manifest.json

{
  "name": "My extension",
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "js": ["contentScript.js"]
    }
  ],
}

service-worker.js

chrome.scripting.registerContentScripts([{
  id : "test",
  matches : [ "https://*.nytimes.com/*" ],
  excludeMatches : [ "*://*/*business*" ],
  js : [ "contentScript.js" ],
}]);

2. Glob 匹配

Glob 属性遵循与匹配模式不同且更灵活的语法。可接受的 glob 字符串是指可能包含通配符和问号的网址。

  • 星号 (*) 匹配任何长度的字符串,包括空字符串
  • 问号 (?) 匹配任何单个字符。

例如,glob https://???.example.com/foo/* 与以下任何一项匹配:

  • https://www.example.com/foo/bar
  • https://the.example.com/foo/

不过,它与以下内容匹配:

  • https://my.example.com/foo/bar
  • https://example.com/foo/
  • https://www.example.com/foo
2.1 示例
  1. 此扩展程序会将内容脚本注入 https://www.nytimes.com/arts/index.html 和 https://www.nytimes.com/jobs/index.htm*,但不会注入 https://www.nytimes.com/sports/index.html

manifest.json

{
  "name": "My extension",
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "include_globs": ["*nytimes.com/???s/*"],
      "js": ["contentScript.js"]
    }
  ],
}
  1. 此扩展程序会将内容脚本注入 https://history.nytimes.com 和 https://.nytimes.com/history,但不会注入 https://science.nytimes.com 或 https://www.nytimes.com/science

manifest.json

{
  "name": "My extension",
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "exclude_globs": ["*science*"],
      "js": ["contentScript.js"]
    }
  ],
}
  1. 全部参数都加上

此扩展程序会将内容脚本注入 https://www.example.com/arts/index.html
https://.example.com/jobs/index.html,但不会注入 https://science.example.comhttps://www.example.com/jobs/businesshttps://www.example.com/science

manifest.json

{
  "content_scripts": [
    {
      "matches": ["https://*.example.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "include_globs": ["*example.com/???s/*"],
      "exclude_globs": ["*science*"],
      "js": ["content-script.js"]
    }
  ],
}

五、运行时间

run_at 字段用于控制何时将 JavaScript 文件注入网页。首选值为 "document_idle"

manifest.json

{
  "name": "My extension",

  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "run_at": "document_idle",
      "js": ["contentScript.js"]
    }
  ],
}

service-worker.js

chrome.scripting.registerContentScripts([{
  id : "test",
  matches : [ "https://*.nytimes.com/*" ],
  runAt : "document_idle",
  js : [ "contentScript.js" ],
}]);

六、允许运行的 iframe

"all_frames" 字段允许该扩展程序指定将 JavaScriptCSS 文件注入到符合指定网址要求的所有框架中,还是仅注入标签页中最顶层的框架。

manifest.json

{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["https://*.nytimes.com/*"],
      "all_frames": true,
      "js": ["contentScript.js"]
    }
  ],
  ...
}

service-worker.js

chrome.scripting.registerContentScripts([{
  id: "test",
  matches : [ "https://*.nytimes.com/*" ],
  allFrames : true,
  js : [ "contentScript.js" ],
}]);
名称 类型 说明
all_frames 布尔值 boolean 可选。默认为 false,表示仅匹配顶部帧。 如果指定 true,所有帧都将注入到,即使帧不是标签页中的最顶层帧也是如此。系统会单独检查每个帧是否符合网址要求。如果不符合网址要求,则不会注入子框架。

七、通信

虽然内容脚本的执行环境和托管它们的页面彼此隔离,但它们共享对页面 DOM 的访问权限。如果网页希望通过内容脚本与内容脚本或扩展程序进行通信,则必须通过共享 DOM 来实现。

可以使用 window.postMessage()

content-script.js

var port = chrome.runtime.connect();
window.addEventListener("message", (event) => {
  // We only accept messages from ourselves
  if (event.source !== window) {
    return;
  }

  if (event.data.type && (event.data.type === "FROM_PAGE")) {
    console.log("Content script received: " + event.data.text);
    port.postMessage(event.data.text);
  }
}, false);

example.js

document.getElementById("theButton").addEventListener("click", () => {
  window.postMessage(
      {type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);

非扩展程序网页 example.html 向自身发布消息。内容脚本拦截和检查此消息,然后发布到扩展程序进程。通过这种方式,页面就能与扩展进程建立通信连接。反之亦然。

八、访问扩展程序文件

如需从内容脚本访问扩展程序文件,可以调用 chrome.runtime.getURL() 来获取扩展程序资源的绝对网址

content-script.js

let image = chrome.runtime.getURL("images/my_image.png")

如需在 CSS 文件中使用字体或图片,可以使用 @@extension_id 构建网址,如以下示例所示 (content.css):

content.css

body {
 background-image:url('chrome-extension://__MSG_@@extension_id__/background.png');
}

@font-face {
 font-family: 'Stint Ultra Expanded';
 font-style: normal;
 font-weight: 400;
 src: url('chrome-extension://__MSG_@@extension_id__/fonts/Stint Ultra Expanded.woff') format('woff');
}

所有资源都必须在 manifest.json 文件中声明为网络可访问资源:

manifest.json

{
 "web_accessible_resources": [
   {
     "resources": [ "images/*.png" ],
     "matches": [ "https://example.com/*" ]
   },
   {
     "resources": [ "fonts/*.woff" ],
     "matches": [ "https://example.com/*" ]
   }
 ],
}

九、禁止事项

1. Eval()

以下为 Manifest V3 禁止使用案例

content-script.js

const data = document.getElementById("json-data");
// WARNING! Might be evaluating an evil script!
const parsed = eval("(" + data + ")");

2. 字符串拼接函数

以下为 Manifest V3 禁止使用案例

content-script.js

const elmt_id = "...";
window.setTimeout("animate(" + elmt_id + ")", 200);

引用

  • 【content-scripts】

到了这里,关于Chrome 插件 V3 版本 Manifest.json 中的内容脚本(Content Scripts)解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题

    总结一下自己在把Chrome V2版本的插件升级到V3版本的过程中,遇到的一些问题,之前也有发布一章V3版本的manifest.json配置项参数说明,基本也涵盖了下面提到的几个配置项的改动,传送门 总结分了两大块,一块是manifest配置文件V2和V3有哪几个配置项不同,一块是升级过程遇到

    2023年04月08日
    浏览(94)
  • 谷歌插件开发:manifest.json 配置文件详解

    在当今的互联网时代,浏览器插件扮演着重要的角色,为用户提供了各种定制化的功能和增强体验。Google Chrome作为最受欢迎的浏览器之一,也提供了丰富的插件生态系统。而在Chrome插件的开发中,manifest.json配置文件起着至关重要的作用。本节将详细讲解manifest.json文件的作用

    2024年02月11日
    浏览(35)
  • chrome V3插件入门到放弃,Plasmo不完全使用指南

    没有插件的浏览器是没有灵魂的。今天来近距离感受一下chrome的灵魂 开始之前了解一下 灵魂 chrome插件的版本。 Chrome 浏览器从88版本开始支持MV3啦(即Manifest Version 3),现在浏览器版本都100+了。而MV2(即Manifest Version 2)将会在2023年 退休 。所以今天要讲的就是MV3版本 后续的

    2024年02月08日
    浏览(42)
  • uniapp在小程序中获取manifest中的版本等配置信息vue2

    vue2版本在根目录新建一个 vue.config.js ,如果没有的话。 写入以下内容 执行的过程 读取 manifest.json 的源文件内容 去掉其中的注释后转为 JSON 数据 写入到 utils/config/version.json ,自己视情况修改路径 读取 import { version } from \\\"utils/config/version.json\\\" 如果有其他要共享的文件也可以这

    2024年02月05日
    浏览(45)
  • 全栈笔记_浏览器扩展篇(插件通信 - 内容脚本与后台脚本通信)

    后台脚本:在后台运行,并在用户与浏览器交互时侦听触发器(例如在选项卡上侦听单击事件) 内容脚本:与网页交互(主要是DOM元素) 一次性消息 内容脚本发送消息给后台脚本:

    2024年02月21日
    浏览(39)
  • Chrome扩展的核心:manifest 文件(下)

    大家好,我是 dom 哥。这是我关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星。 在上篇和中篇中已经完成了对 manifest 文件中以下字段的解释: \\\"manifest_version\\\" \\\"name\\\" \\\"version\\\" \\\"description\\\" \\\"icons\\\" \\\"content_scripts\\\" \\\"background\\\" \\\"permissions\\\" 本篇接着说剩下的 manifest 可选字段。 定义

    2024年02月04日
    浏览(49)
  • Chrome扩展的核心:manifest 文件(中)

    大家好,我是 dom 哥。我正在写关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星 。 在上一篇中已经完成了 Chrome 扩展的雏形,本篇接着介绍 manifest 中的可选字段,完善扩展的细节。 向 web 页面注入 JavaScript 和 CSS 。可以说这是 Chrome 扩展的灵魂。当指定 content_scri

    2024年02月04日
    浏览(46)
  • Chrome扩展的核心:manifest 文件(上)

    大家好,我是dom哥。我正在写关于 Chrome 扩展开发的系列文章,感兴趣的可以点个小星星。 Chrome 在全球浏览器市场份额独占 6 成,无论是对普通用户还是开发者,都是电脑里的必备利器。Chrome 无论是在性能还是 UI 交互方面都非常出色,而 Chrome 扩展则为开发者提供了接口,

    2024年02月05日
    浏览(41)
  • 谷歌chrome浏览器所有历史版本下载及selenium自动化控制插件资源分享

    使用python + selenium做网页自动化开发的小伙伴经常需要用到google chrome浏览器以及chromedriver插件。     谷歌浏览器所有历史版本下载链接: chrome历史版本,点击下载 chromedriver插件下载地址: 下载链接1:点击下载 下载链接2:点击下载 chromedriver插件与浏览器版本有对应关系,

    2024年02月14日
    浏览(56)
  • Chrome浏览器中的vue插件devtools的下载方式(使用Chrome应用商店/科学上网情况下)

    目录 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等  下载步骤:  测试阶段:  最近做项目要使用devtools这个vue插件。 首先先想个办法搞个加速器之类的,好实现科学上网。 在Chrome浏览器中访问以下网址: Chrome应用商店网址: https://c

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包