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

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_atRunAt可选。指定应将脚本注入网页的时间。默认为 document_idle
match_about_blank布尔值 boolean可选。脚本是否应注入到 about:blank 帧中,其中父帧或起始帧与 matches 中声明的模式之一匹配。默认值为 false
match_origin_as_fallback布尔值 boolean可选。脚本是否应在由匹配的来源创建但其网址或来源可能与模式不直接匹配的帧中注入。其中包括采用不同架构的帧,例如 about:data:blob: 和 filesystem:
worldExecutionWorld可选。要在其中执行脚本的 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 ourselvesif (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】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/623610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有哪些品牌的超声波清洗机是值得入手的?超声波清洗机推荐

作为一个既对生活品质有追求&#xff0c;又只想躺平的懒人&#xff0c;一直在努力尝试让轻松的生活少一点绊脚石&#xff0c;而其中最重要的一个&#xff0c;就是清洗眼镜清洗日常生活的一些小物件&#xff0c;讲真&#xff0c;洗这些东西有时候就跟下班回家的KPI一样。白天不累…

SearchInsertPosition【搜索插入位置】

给定的数组已经排序&#xff0c;找到第一个不小于给定值就可以了。 public int searchInsert(int[] nums, int target) {for(int i0;i<nums.length;i){//数组中存在&#xff0c;返回下标if(nums[i] target){return i;}//数组中不存在&#xff0c;需插入到数组中间位置情况…

《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(6)-Fiddler状态面板详解

1.简介 按照从上往下&#xff0c;从左往右的计划&#xff0c;今天就轮到介绍和分享Fiddler的状态面板了。 2.状态面板概览 Fiddler的状态面板概览&#xff0c;如下图所示&#xff1a; 3.状态面板详解 Fiddler底端状态栏面板详解&#xff0c;如下图所示&#xff1a; 3.1Captu…

重新分区扩展C盘

电脑 – 管理 使用第三方工具&#xff1a;DiskGenius数据恢复及分区管理软件 要选择完成后重启 &#xff0c;如果这里忘记勾选&#xff0c;后面也会再次提醒并默认勾选重启 "调整后容量"是指图片上显示的非C盘之外的盘符的容量&#xff0c;这里指E盘大小 上面已经利…

vue知识-05

聊天室案例(django接口) # chat.hetm<<script src"/static/axios.js"></script><script src"/static/vue.js"></script><body> <div id"app"><h1>聊天室</h1><button click"handleS…

解读vue配置文件(vue.config.js)

use strict const path require(path) const defaultSettings require(./src/settings.js) const CompressionPlugin require(compression-webpack-plugin)function resolve(dir) {return path.join(__dirname, dir) }const name defaultSettings.title // 网址标题 const …

浏览器事件循环(事件轮询)

浏览器事件循环(事件轮询) 文章目录 浏览器事件循环(事件轮询)1.浏览器事件循环流程2.同步任务、异步任务、宏任务和微任务概念同步任务&#xff1a;异步任务&#xff1a;宏任务&#xff1a;微任务&#xff1a; 3.宏任务和微任务区别异步任务的分类&#xff1a;异步任务执行顺序…

从事铁路工作保护足部,穿什么劳保鞋更安全

铁路运输在我国交通运输业中起着骨干作用&#xff0c;为国民经济的可持续发展和人口流动做出了巨大贡献。安全是铁路运输不可忽视的问题&#xff0c;在作业场地随处能见到“安全就是生命&#xff0c;责任重于泰山”的安全标语&#xff0c;由此可见安全问题是放在首位的。 铁路施…

PyTorch深度学习实战(30)——Deepfakes

PyTorch深度学习实战&#xff08;30&#xff09;——Deepfakes 0. 前言1. Deepfakes 原理2. 数据集分析3. 使用 PyTorch 实现 Deepfakes3.1 random_warp.py3.2 Deepfakes.py 小结系列链接 0. 前言 Deepfakes 是一种利用深度学习技术生成伪造视频和图像的技术。它通过将一个人的…

用python实现word中所有图片变清晰

要使用Python将Word文档中的所有图片变清晰&#xff0c;你需要使用一些库&#xff0c;例如python-docx和OpenCV。以下是一个简单的示例&#xff0c;说明如何使用这些库来提高Word文档中图片的清晰度。 请注意&#xff0c;这种方法基于简单的图像增强技术&#xff0c;可能无法提…

学习Vue配置代理总结

今天学习了Vue的配置代理&#xff0c;当我们想要向服务器取回来数据时就先要向服务器发送请求&#xff0c;但前端发送请求的方式也有很多种&#xff0c;首先是发送请求的鼻祖JS的XMLHttpRequest&#xff08;xhr&#xff09;&#xff0c;它操作起来相对麻烦&#xff0c;开发中也…

SpringBoot自定义Starter(@EnableXXX和META-INF的SPI自动添加)

目录 1. 自定义Starter1.1 场景和效果1.2 starter实现1.2.1 创建自定义starter项目1.2.2 把所有maven依赖导入1.2.3 实现公共代码逻辑1.2.4 添加方式一&#xff1a;实现RobotAutoConfiguration配置类1.2.5 添加方式二&#xff1a;实现RobotAutoConfiguration配置类 EnableRobo…

大数据日志数据量过大如何处理

如果是web端的埋点数据&#xff0c;我们可以对这些数据进行分流。 我们可以采用事件分流&#xff0c;步骤如下 定义事件类型&#xff1a; 根据埋点数据的内容&#xff0c;定义不同的事件类型。例如&#xff0c;可以有页面访问事件、按钮点击事件、表单提交事件等。 提取关键信…

Linux下如何快速调试I2C设备

Linux下如何快速调试I2C设备 目录 1 什么场景下需要快速调试I2C设备 2 如何快速调试I2C设备 3 如何获取I2C Tools工具集 3.1 获取I2C Tools工具集源码 3.2 编译I2C Tools工具集源码 3.3 为设备添加I2C Tools工具集 4 如何使用I2C Tools工具集 5 小结 1 什么场景下需要快…

强化app广告变现用户隐私合规,移动广告变现合规技巧

移动广告技术的发展帮助开发者极大提升了广告变现效率&#xff0c;APP作为用户个人信息处理的重要载体&#xff0c;自从《个人信息保护法》颁布以来&#xff0c;个人信息的使用已经成为监管重点&#xff0c;开发者强化合规意识&#xff0c;让广告变现业务“细水长流”&#xff…

Ansible Filter滤波器的使用

一、【说在前面】 Ansible Filter一般被称为滤波器或者叫过滤器。 这个东西初次听到以为是什么科学计算的东西&#xff0c;但是想来ansible不太可能有什么滤波操作&#xff0c;所以这个东西本质是一个数值筛选器&#xff0c;内置函数&#xff0c;本质是一个为了做区别化的工具…

AcrelEMS-CB商业建筑能源管理系统解决方案-安科瑞 蒋静

1概述 AcrelEMS-CB商业建筑能源管理系统&#xff0c;集电力监控、电能质量监测与治理、电气安全预警、能耗分析、照明控制、新能源使用、能源收费以及设备运维等功能于一体&#xff0c;通过一套系统对商业建筑的能源进行统一监控、统一运维和调度&#xff0c;系统可以通过WEB和…

QT基础篇(6)QT5图形与图片

1.QT5位置相关函数 在Qt5中&#xff0c;有一些与位置相关的函数可以帮助您处理窗口和控件的位置。下面是一些常用的位置相关函数&#xff1a; move(x, y): 将窗口或控件移动到屏幕上的指定位置&#xff0c;其中x和y表示要移动到的坐标。 resize(width, height): 调整窗口或控…

go切片参数传递用值还是指针

Go 中常用的切片 slice 数据结构是动态数组&#xff0c;切片长度并不固定&#xff0c;在容量不足的时候会自动扩容。 切片实质上是对一个底层数组的抽象视图&#xff0c;由 Go 运行时维护。在运行时&#xff0c;切片由如下的 SliceHeader 结构体表示&#xff0c;其中 Data 字段…

机器人说明书---名词解释030课_python语言_方法重写

这里写自定义目录标题 方法重写类属性与方法类的私有属性类的方法类的私有方法实例类的私有方法实例如下&#xff1a; 类的专有方法&#xff1a;视频讲解 方法重写 如果你的父类方法的功能不能满足你的需求&#xff0c;你可以在子类重写你父类的方法&#xff0c;实例如下&…