Chrome 浏览器插件获取网页 window 对象(方案三)

2024-09-05 12:12

本文主要是介绍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. 方案思路

  1. 新建两个 js 文件,index.jslucky.js
  2. content_scripts 中嵌入 lucky.js 文件和 index.js 文件
  3. index.js 中通过 window.dispatchEvent 派发自定义 custom event 消息
  4. index.js 中通过 addEventListener 监听消息
  5. 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.detailif (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.detailswitch (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. 代码地址

  • Gitee
  • Github

四、总结

1. 文章总结

  1. 获取当前页面下的 window 对象和 document 对象不一样,需要另外的处理方式
  2. 此次提供了三种方案,核心原理都是嵌入当前页面,通过消息派发和接收来获取数据
  3. 第一种通过 postMessage 的方式更为大家熟悉,自定义 Event 相对偏一点
  4. 三种方案的代码我都上传到 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 对象(方案三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138931

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

如何选择SDR无线图传方案

在开源软件定义无线电(SDR)领域,有几个项目提供了无线图传的解决方案。以下是一些开源SDR无线图传方案: 1. **OpenHD**:这是一个远程高清数字图像传输的开源解决方案,它使用SDR技术来实现高清视频的无线传输。OpenHD项目提供了一个完整的工具链,包括发射器和接收器的硬件设计以及相应的软件。 2. **USRP(Universal Software Radio Periphera

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

禁止复制的网页怎么复制

禁止复制的网页怎么复制 文章目录 禁止复制的网页怎么复制前言准备工作操作步骤一、在浏览器菜单中找到“开发者工具”二、点击“检查元素(inspect element)”按钮三、在网页中选取需要的片段,锁定对应的元素四、复制被选中的元素五、粘贴到记事本,以`.html`为后缀命名六、打开`xxx.html`,优雅地复制 前言 在浏览网页的时候,有的网页内容无法复制。比如「360

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR