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

news/2024/9/27 15:31:00

前言

最近有个需求,是在浏览器插件中获取 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. 方案流程

流程图如下:

image

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 对象

image

4. 动态获取参数

如果想通过点击等操作获取数据,则方法如下

4.1. 实现流程

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

流程图如下:

image

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】

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

1.项目目录

1.AppScope 全局公共资源(常量、图片)存放路径 2.entry 工程模块(开发)目录 3.hvigor 基于ts实现的前端构建和任务编程的工具(npm) 4.oh_modules 依赖包 5.build-profile.json5 项目级别的配置信息 6.local.properties 本地基本信息 7.oh-package.json5 依赖关系配置和基…

代码随想录day50 || 图论基础

图论 基础定义图的构造方式 1,邻接矩阵矩阵位置array[i][j] = k, i表示节点i,j表示节点j,[i][j] 表示i-->j存在一条边,k表示的是边的权重邻接矩阵的优点: 表达方式简单,易于理解 检查任意两个顶点间是否存在边的操作非常快 适合稠密图,在边数接近顶点数平方的图中,邻…

Victoria 3 入门心得

一、简介 Victoria 3是一款模拟策略类游戏。系统需求如下:二、开局 1. 外交 外交有两个原则,一是平等,二是市场。平等要求这个国家不能有敌意,且政🍊稳定。还要搞清楚国与国之间的关系,要站好队。至于市场,看国内有什么需求,在满足平等的条件下进行外交。注意,一但建…

DNF完美仿官90版本单机安装教程 + 虚拟机一键端

前言 今天给大家带来一款单机游戏的架设:地下城与勇士 90 版单机安装。 另外:本人承接各种游戏架设(单机+联网) 本人为了学习和研究软件内含的设计思想和原理,带了架设教程仅供娱乐。 教程是本人亲自搭建成功的,绝对是完整可运行的,踩过的坑都给你们填上了。 如果你是小…

Camstar MDB setfieldex 修改建模字段不記錄Audit Trail

1. 在clf中使用setfieldex直接賦值,對於的建模對象不會記錄Audit Trail2.現在需求是:clf通過setfieldex修改對應建模的字段,需要記錄對於的Audit Trail3.步驟1:先確保對於的見面對象有記錄Audit Trail 4.步驟2:除了setfieldex 直接賦值邏輯外,需要調用對於建模的Maint服…

把python项目部署在docker上

前提,已经安装好docker了,docker的安装,请见另一篇博客 介绍一下需要运行的python项目结构,平时在pycharm里面只需要运行app.py文件即可 项目步骤如下: 1:创建一个上传到Centos系统的文件夹(名字随意) docker_svnhook是要上传到Linux系统,生成Dokcer镜像的文件夹这个…

超级快速搜索重复文件并批量删除重复文件的AutoHotkey辅助脚本 2024年9月4日

超级快速搜索重复文件并批量删除重复文件的AutoHotkey辅助脚本 2024年9月4日; 超级快速搜索重复文件并批量删除重复文件的AutoHotkey辅助脚本 2024年9月4日/* 用法:1、安装 MasterSeeker 1.5.1 by DxCK 或者安装 UltraSearch Professional Version 4.2.0.925 64位2、安装 Dupl…

pip install 安装时,提示【 Could not install packages due to an OSError: [Errno 13] Permission denied】

参考资料:【Python】已解决:ERROR: Could not install packages due to an OSError: [WinError 5] 拒绝访问。 我的问题: 使用pip install 安装时,遇到【Could not install packages due to an OSError: [Errno 13] Permission denied】的错误,提示可能需要【--user】选项…