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

2024-09-04 17:20

本文主要是介绍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 对象(方案一)

一、两个文件,通过 CustomEvent 传递消息

1. 方案思路

  1. 新建两个 js 文件,index.jslucky.js
  2. content_scripts 中嵌入 index.js 文件
  3. index.js 中通过 script 标签,嵌入 lucky.js
  4. index.js 中通过 window.dispatchEvent 派发自定义 custom event 消息;派发消息的内容为一个函数转换的字符串,函数返回的内容则为你需要获取的 window 下的对象值
  5. lucky.js 中通过 addEventListener 监听消息,再通过 dispatchEvent 派发消息;监听到对应的 custom eventtype 的时候,进行参数函数的执行,通过 new Function() 的方式执行,并获取返回值,再进行消息派发到 index.js 文件
  6. index.js 中通过 addEventListener 监听消息拿到对应的值
  7. manifest.json 文件中添加 web_accessible_resources
1.1. 方案流程

流程图如下:

画板

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 = () => {const script = document.createElement('script')script.src = chrome.runtime.getURL('lucky.js')document.head.appendChild(script)// lucky.js 加载setTimeout(() => sendMessage(), 100)// script.onload = () => {//   sendMessage()// }// 插入 button 按钮const button = document.createElement('button')button.innerText = '获取数据'button.id = 'chrome-ext-but'document.body.appendChild(button)button.onclick = () => {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": ["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": [{"resources": ["lucky.js"],"matches": ["http://localhost:*/*"],"use_dynamic_url": true}]
}
3.4. 项目文件结构
.
├── index.html
├── index.js
├── lucky.js
├── manifest.json
└── service-worker.js
3.5. 方案效果

在控制台中选择当前插件,即可查看获取的 window 下的 MyBlog 对象

4. 动态获取数据

4.1. 实现思路
  1. index.js 文件中动态插入 button 按钮到当前页面
  2. 绑定 click 事件,
  3. 点击的时候触发 index.js 文件的派发事件,并进行数据监听
  4. 拿到对应的数据再进行操作
4.2. 点击按钮

4.3. 数据返回

5. 代码地址

  • Gitee
  • Github

参考

  • 【Content_script】
  • 【CustomEvent:CustomEvent() 构造函数】

这篇关于Chrome 浏览器插件获取网页 window 对象(方案二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave