Chrome 浏览器插件获取网页 window 对象(方案三)
前言
最近有个需求,是在浏览器插件中获取 window 对象下的某个数据,当时觉得很简单,和 document 一样,直接通过嵌入 content_scripts 直接获取,然后使用 sendMessage 发送数据到插件就行了,结果发现不是这样滴...
在这里不推荐使用
runtime.executeScript进行注入,很可能会报错:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost http://127.0.0.1". Either the 'unsafe-inline' keyword, a hash ('sha256-P5exJBBLYN1KVh+CK9MkXvRal4ZQQu9VaKPvx4JuVLE='), or a nonce ('nonce-...') is required to enable inline execution.
Chrome 浏览器插件获取网页 window 对象(方案一)
Chrome 浏览器插件获取网页 window 对象(方案二)
一、两个文件,通过 CustomEvent 传递消息
1. 方案思路
- 新建两个
js文件,index.js和lucky.js - 在
content_scripts中嵌入lucky.js文件和index.js文件 - 在
index.js中通过window.dispatchEvent派发自定义custom event消息 - 在
index.js中通过addEventListener监听消息 - 在
lucky.js中通过addEventListener监听消息,再通过dispatchEvent派发消息
1.1. content_scripts 嵌入 JS 文件
一定要把 lucky.js 文件放在 index.js 文件前面
content_scripts 中添加 lucky.js 的时候需要加上 "world": "MAIN" 字段
world 为枚举类型
ISOLATED默认值- 此扩展程序所独有的执行环境
MAIN- 指定
DOM的主域,也就是与托管页面的JavaScript共享的执行环境
- 指定
1.2. 方案流程
流程图如下:

2. 获取内容
获取
window下的MyBlog字段
window.MyBlog = {
juejin: 'https://juejin.cn/user/2409752520033768/posts',
csdn: 'https://guoqiankun.blog.csdn.net/',
'chrome-blog': {
netlify: 'https://gqk-extension.netlify.app/',
github: 'https://18055975947.github.io/extension/'
}
}
3. 实现代码
3.1. index.js
/**
* index 文件发送消息到 lucky.js 文件
* @param {string} type custom 类型
* @param {any} data 数据
*/
const indexSendMessageToLucky = async (type, data) => {
window.dispatchEvent(new CustomEvent('custom-index-type', { detail: { type, data } }))
return new Promise((res) => {
function handleResponse(e) {
const detail = e.detail
if (detail.type == type) {
window.removeEventListener('custom-lucky-type', handleResponse)
return res(detail.data)
}
}
window.addEventListener('custom-lucky-type', handleResponse)
})
}
/**
* 发送消息
*/
const sendMessage = () => {
function getMyBolg() {
return window.MyBlog
}
indexSendMessageToLucky('run-index-fun', {
function: getMyBolg.toString()
}).then((res) => {
console.log('res-->', res)
}).catch((e) => {
console.log('e', e)
})
}
/**
* 初始化
*/
const init = () => {
// 插入 button 按钮
const button = document.createElement('button')
button.innerText = '获取数据'
button.id = 'chrome-ext-but'
document.body.appendChild(button)
button.onclick = () => {
sendMessage()
}
// 初始化获取数据
sendMessage()
}
// 判断 window.top 和 self 是否相等,如果不相等,则不注入
if (window.top == window.self) {
init()
}
3.2. lucky.js
/**
* 事件监听
*/
window.addEventListener('custom-index-type', async (e) => {
const { type, data } = e.detail
switch (type) {
case 'run-index-fun': {
const fn = new Function(`return (${data.function})(...arguments)`)
const rs = await fn(...(data.args ?? []))
luckySendMessageToIndex(type, rs)
break
}
}
})
/**
* lucky 文件发送消息到 index.js 文件
* @param {string} type custom 类型
* @param {any} data 数据
*/
const luckySendMessageToIndex = (type, data) => {
window.dispatchEvent(
new CustomEvent('custom-lucky-type', {
detail: { type, data, file: 'lucky' }
})
)
}
3.3. manifest.json
{
"manifest_version": 3,
"name": "Get Winddow Object Field",
"version": "1.0",
"description": "Gets the field under window",
"content_scripts": [
{
"js": [
"lucky.js"
],
"matches": ["http://localhost:*/*"],
"run_at": "document_end",
"world": "MAIN"
},
{
"js": [
"index.js"
],
"matches": ["http://localhost:*/*"],
"all_frames": true,
"run_at": "document_end"
}
],
"background": {
"service_worker": "service-worker.js"
},
"host_permissions": [
"http://localhost:*/*"
],
"permissions": [
],
"web_accessible_resources": []
}
3.4. 项目文件结构
.
├── index.html
├── index.js
├── lucky.js
├── manifest.json
└── service-worker.js
3.5. 方案效果
在控制台中选择当前插件,即可查看获取的 window 下的 MyBlog 对象

4. 动态获取数据
4.1. 点击按钮

4.2. 数据返回

5. 代码地址
四、总结
1. 文章总结
- 获取当前页面下的 window 对象和 document 对象不一样,需要另外的处理方式
- 此次提供了三种方案,核心原理都是嵌入当前页面,通过消息派发和接收来获取数据
- 第一种通过 postMessage 的方式更为大家熟悉,自定义 Event 相对偏一点
- 三种方案的代码我都上传到 gitee/github 上了
2. 代码地址
- Gitee:https://gitee.com/gqk-chrome-extension/get-window-fields
- Github:https://github.com/gqk-chrome-extension/get-window-fields/tree/main
引用
- 【chrome extensions mv3通过content scripts注入/获取原网站的window数据】
- 【CustomEvent:CustomEvent() 构造函数】
- 【Content_script world】
Chrome 浏览器插件获取网页 window 对象(方案三)的更多相关文章
- 使用 Chrome 浏览器插件 Web Scraper 10分钟轻松实现网页数据的爬取
web scraper 下载:Web-Scraper_v0.2.0.10 使用 Chrome 浏览器插件 Web Scraper 可以轻松实现网页数据的爬取,不写代码,鼠标操作,点哪爬哪,还不用考虑爬 ...
- chrome浏览器插件window resizer调试webapp页面大小
chrome浏览器插件window resizer可以调整当前浏览器分辨率大小 可以自定义大小,以适合于andorid和iphone设备
- Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件
Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件 下载地址 插件的操作很简单,下面是一些简单的实例. 1.安装 在谷歌应用商城搜索postman,如下图1-1所 ...
- 用Javascript编写Chrome浏览器插件
原文:http://homepage.yesky.com/62/11206062.shtml 用Javascript编写Chrome浏览器插件 2010-04-12 07:30 来源:天极网软件频道 ...
- chrome浏览器插件开发经验(一)
最近在进行chrome浏览器插件的开发,一些小的经验总结随笔. 1.首先,推荐360的chrome插件开发文档:http://open.chrome.360.cn/extension_dev/over ...
- 还在为百度网盘下载速度太慢烦恼?chrome浏览器插件帮你解决!
百度网盘已然成为分享型网盘中一家独大的“大佬”了.时代就是这样不管你喜不喜欢,上网总会遇到些百度网盘共享的文件需要下载.然而,百度网盘对免费用户的限速已经到了“感人”的地步了,常常十多KB/秒的速度真 ...
- 强烈推荐 10 款珍藏的 Chrome 浏览器插件
Firebug 的年代,我是火狐(Mozilla Firefox)浏览器的死忠:但后来不知道为什么,该插件停止了开发,导致我不得不寻求一个新的网页开发工具.那段时间,不少人开始推荐 Chrome 浏览 ...
- chrome浏览器插件启动本地应用程序
chrome浏览器插件启动本地应用程序 2014-04-20 00:04:30| 分类: 浏览器插件|举报|字号 订阅 下载LOFTER我的照片书 | chrome的插件开发这里就 ...
- 通过chrome console 快速获取网页连接
通过chrome console 快速获取网页连接 var ip = document.getElementsByClassName("jDesc"); var str = &qu ...
- chrome浏览器页面获取绑定返回顶部动画事件插件
在chrome浏览器下页面加载: var top = $("body").scrollTop() ; console.log(top) ...
随机推荐
- 把nodejs程序打包成可执行文件
在写好之后的nodejs程序,想发给同事的电脑上运行程序,就不得不下载node环境,还要安装第三方依赖包,非常的麻烦. 因此,可以借助一些插件来完成nodejs程序的打包,变成可以执行的文件. 将No ...
- Azure Function 时区设置
一,引言 Azure Function 上的默认使用UTC 运行程序,我们在获取时间,或者通过时间执行某些逻辑时,返回UTC 时间,导致业务数据不正常,由于 Azure Function 是微软提供的 ...
- leetcode中等(字符串):[3, 6, 8, 49, 179, 299, 524, 539, 609, 648]
目录 3. 无重复字符的最长子串 6. Z 字形变换 8. 字符串转换整数 (atoi) 49. 字母异位词分组 179. 最大数 299. 猜数字游戏 524. 通过删除字母匹配到字典里最长单词 5 ...
- Python win11 安装lxml 失败
如果你有一个项目执行了requirements后,一直提示lxml失败,解决步骤如下 1.尝试升级pip python.exe -m pip install --upgrade pip 2.尝试下载包 ...
- 前缀函数及 Knuth–Morris–Pratt 算法学习笔记
\(\text{1 引言 Preface}\) 对于形如以下的问题: 给予一个模式串 \(T\) 和主串 \(S\),在主串中寻找 \(T\). 我们称之为字符串匹配. 很显然朴素算法时间复杂度是 \ ...
- 2023/4/21 SCRUM个人博客
1.我昨天的任务 学习信号和槽的定义并完善UI界面的基础知识 2.遇到了什么困难 难以理解design的设计理念 3.我今天的任务 学习如何使用QTdesign,并完善UI
- SemanticKernel/C#:使用Ollama中的对话模型与嵌入模型用于本地离线场景
前言 上一篇文章介绍了使用SemanticKernel/C#的RAG简易实践,在上篇文章中我使用的是兼容OpenAI格式的在线API,但实际上会有很多本地离线的场景.今天跟大家介绍一下在Semanti ...
- 【Spring-Security】Re04 Matchers配置规则API
一.使用antMatchers放行静态资源: package cn.zeal4j.configuration; import cn.zeal4j.handler.FarsAuthenticationF ...
- openAI的仿真环境Gym Retro的Python API接口
如题,本文主要介绍仿真环境Gym Retro的Python API接口 . 官网地址: https://retro.readthedocs.io/en/latest/python.html ===== ...
- 不符合自身利益的科学讨论是否应该得到尊重—— 读《自家员工质疑Jeff Dean领衔的Nature论文被解雇,谷歌:我们彻查了,质疑不符合标准》有感
读了一篇博文<自家员工质疑Jeff Dean领衔的Nature论文被解雇,谷歌:我们彻查了,质疑不符合标准>,其问大致是说Google提了一篇使用reinforcement learnin ...