当前位置: 首页 > news >正文

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.

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

1. 方案思路

  1. 新建两个 js 文件,index.jslucky.js
  2. content_scripts 中嵌入 index.js 文件
  3. index.js 中通过 script 标签,嵌入 lucky.js
  4. index.js 中通过 window.addEventListener('message') 监听消息
  5. lucky.js 中通过 window.postMessage 进行消息传递
  6. 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
const init = () => {const script = document.createElement('script')script.src = chrome.runtime.getURL('lucky.js')document.head.appendChild(script)// 监听从页面上下文发回的消息window.addEventListener('message', (event) => {console.log('event', event)if (event.source !== window) returnif (event.data.type === 'get-window-data') {console.log('window data:', event.data.data)}})
}// 判断 window.top 和 self 是否相等,如果不相等,则不注入
if (window.top == window.self) {init()
}
3.2. lucky.js
window.postMessage({type: 'get-window-data',data: window.MyBlog,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. 实现流程

如果想通过页面按钮点击再获取数据,也是通过 postMessage 发送消息,以及通过 addEventListener 接收消息再次发送到插件

流程图如下:

画板

4.2. 实现代码
4.2.1. index.js
/*** 发送消息* @param {string} type 类型* @param {string} field 获取的字段名称*/
const postMessage = (type, field) => {window.postMessage({type,field,file: 'index'})
}
/*** 初始化*/
const init = () => {const script = document.createElement('script')script.src = chrome.runtime.getURL('lucky.js')document.head.appendChild(script)// 监听从页面上下文发回的消息window.addEventListener('message', (event) => {console.log('event', event)if (event.source !== window) returnif (event.data.type === 'get-window-data') {console.log('window data:', event.data.data)}})// 加入定时器是因为 lucky.js 加载需要时间,如果不需要初始化就获取数据,可以把这行删除// 如果想初始化就获取数据,又不想加 setTimeout,就把下面 lucky.js 注释的代码放开就行setTimeout(() => postMessage('get-window-field', 'MyBlog'), 100)// 或者在 script onload 的时候进行消息发送// script.onload = () => {//   postMessage('get-window-field', 'MyBlog')// }// 插入 button 按钮const button = document.createElement('button')button.innerText = '获取数据'button.id = 'chrome-ext-but'document.body.appendChild(button)button.onclick = () => {postMessage('get-window-field', 'MyBlog')}
}// 判断 window.top 和 self 是否相等,如果不相等,则不注入
if (window.top == window.self) {init()
}
4.2.2. 点击按钮获取数据

4.2.3. lucky.js
// 如果想初始化就传递消息,也不想加 setTimeout,则放开下面的代码
// window.postMessage({
//   type: 'get-window-data',
//   data: window.MyBlog,
//   file: 'lucky'
// })/*** 监听 message 消息*/
window.addEventListener('message', (event) => {if (event.data?.type === 'get-window-field') {window.postMessage({type: 'get-window-data',data: window[event.data.field],file: 'lucky'})}
})

5. 代码地址

  • 【Gitee】
  • 【Github】

参考

  • 【postMessage】
  • 【Content_script】

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java 入门指南:Java NIO —— Buffer(缓冲区)
  • 【体检】程序人生之健康检查,全身体检与预防疫苗,五大传染病普筛,基因检测等
  • 你知道吗?Python现在这么火爆的真相!
  • RKNPU2项目实战【1】 ---- YOLOv5实时目标分类
  • sealos快速搭建k8s集群
  • 【深度学习】线性回归的从零开始实现与简洁实现
  • Netty实现WebSocket及分布式解决方案
  • 优思学院|六西格玛,质量人不可错过的宝典,一篇文章让你读懂六西格玛!
  • 线程间数据传递之ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal
  • 什么是云计算?
  • 详解 MQ 消息队列
  • List
  • ElasticSearch-Ingest Pipeline Painless Script
  • Java经典框架之MyBatis
  • 分享购买率拉满的8个商品详情页设计技巧!
  • CEF与代理
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • HTTP中的ETag在移动客户端的应用
  • JavaScript DOM 10 - 滚动
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JS题目及答案整理
  • node和express搭建代理服务器(源码)
  • Puppeteer:浏览器控制器
  • React-flux杂记
  • Vim Clutch | 面向脚踏板编程……
  • Vue UI框架库开发介绍
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 创建一个Struts2项目maven 方式
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 大主子表关联的性能优化方法
  • 订阅Forge Viewer所有的事件
  • 读懂package.json -- 依赖管理
  • 规范化安全开发 KOA 手脚架
  • 理解在java “”i=i++;”所发生的事情
  • 聊聊sentinel的DegradeSlot
  • 你真的知道 == 和 equals 的区别吗?
  • 算法系列——算法入门之递归分而治之思想的实现
  • 微信小程序--------语音识别(前端自己也能玩)
  • 小李飞刀:SQL题目刷起来!
  • 找一份好的前端工作,起点很重要
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • # centos7下FFmpeg环境部署记录
  • #stm32整理(一)flash读写
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • $(function(){})与(function($){....})(jQuery)的区别
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (四) Graphivz 颜色选择