前言

最近有个需求,是在浏览器插件中获取 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.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. 文章总结

  1. 获取当前页面下的 window 对象和 document 对象不一样,需要另外的处理方式
  2. 此次提供了三种方案,核心原理都是嵌入当前页面,通过消息派发和接收来获取数据
  3. 第一种通过 postMessage 的方式更为大家熟悉,自定义 Event 相对偏一点
  4. 三种方案的代码我都上传到 gitee/github 上了

2. 代码地址

引用

Chrome 浏览器插件获取网页 window 对象(方案三)的更多相关文章

  1. 使用 Chrome 浏览器插件 Web Scraper 10分钟轻松实现网页数据的爬取

    web scraper 下载:Web-Scraper_v0.2.0.10 使用 Chrome 浏览器插件 Web Scraper 可以轻松实现网页数据的爬取,不写代码,鼠标操作,点哪爬哪,还不用考虑爬 ...

  2. chrome浏览器插件window resizer调试webapp页面大小

    chrome浏览器插件window resizer可以调整当前浏览器分辨率大小 可以自定义大小,以适合于andorid和iphone设备

  3. Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件

    Rest Client(Rest接口调试工具,有保存功配置功能) chrome浏览器插件 下载地址 插件的操作很简单,下面是一些简单的实例. 1.安装 在谷歌应用商城搜索postman,如下图1-1所 ...

  4. 用Javascript编写Chrome浏览器插件

    原文:http://homepage.yesky.com/62/11206062.shtml 用Javascript编写Chrome浏览器插件 2010-04-12 07:30 来源:天极网软件频道 ...

  5. chrome浏览器插件开发经验(一)

    最近在进行chrome浏览器插件的开发,一些小的经验总结随笔. 1.首先,推荐360的chrome插件开发文档:http://open.chrome.360.cn/extension_dev/over ...

  6. 还在为百度网盘下载速度太慢烦恼?chrome浏览器插件帮你解决!

    百度网盘已然成为分享型网盘中一家独大的“大佬”了.时代就是这样不管你喜不喜欢,上网总会遇到些百度网盘共享的文件需要下载.然而,百度网盘对免费用户的限速已经到了“感人”的地步了,常常十多KB/秒的速度真 ...

  7. 强烈推荐 10 款珍藏的 Chrome 浏览器插件

    Firebug 的年代,我是火狐(Mozilla Firefox)浏览器的死忠:但后来不知道为什么,该插件停止了开发,导致我不得不寻求一个新的网页开发工具.那段时间,不少人开始推荐 Chrome 浏览 ...

  8. chrome浏览器插件启动本地应用程序

    chrome浏览器插件启动本地应用程序 2014-04-20 00:04:30|  分类: 浏览器插件|举报|字号 订阅     下载LOFTER我的照片书  |     chrome的插件开发这里就 ...

  9. 通过chrome console 快速获取网页连接

    通过chrome console 快速获取网页连接 var ip = document.getElementsByClassName("jDesc"); var str = &qu ...

  10. chrome浏览器页面获取绑定返回顶部动画事件插件

    在chrome浏览器下页面加载: var top = $("body").scrollTop()  ; console.log(top)                      ...

随机推荐

  1. 把nodejs程序打包成可执行文件

    在写好之后的nodejs程序,想发给同事的电脑上运行程序,就不得不下载node环境,还要安装第三方依赖包,非常的麻烦. 因此,可以借助一些插件来完成nodejs程序的打包,变成可以执行的文件. 将No ...

  2. Azure Function 时区设置

    一,引言 Azure Function 上的默认使用UTC 运行程序,我们在获取时间,或者通过时间执行某些逻辑时,返回UTC 时间,导致业务数据不正常,由于 Azure Function 是微软提供的 ...

  3. leetcode中等(字符串):[3, 6, 8, 49, 179, 299, 524, 539, 609, 648]

    目录 3. 无重复字符的最长子串 6. Z 字形变换 8. 字符串转换整数 (atoi) 49. 字母异位词分组 179. 最大数 299. 猜数字游戏 524. 通过删除字母匹配到字典里最长单词 5 ...

  4. Python win11 安装lxml 失败

    如果你有一个项目执行了requirements后,一直提示lxml失败,解决步骤如下 1.尝试升级pip python.exe -m pip install --upgrade pip 2.尝试下载包 ...

  5. 前缀函数及 Knuth–Morris–Pratt 算法学习笔记

    \(\text{1 引言 Preface}\) 对于形如以下的问题: 给予一个模式串 \(T\) 和主串 \(S\),在主串中寻找 \(T\). 我们称之为字符串匹配. 很显然朴素算法时间复杂度是 \ ...

  6. 2023/4/21 SCRUM个人博客

    1.我昨天的任务 学习信号和槽的定义并完善UI界面的基础知识 2.遇到了什么困难 难以理解design的设计理念 3.我今天的任务 学习如何使用QTdesign,并完善UI

  7. SemanticKernel/C#:使用Ollama中的对话模型与嵌入模型用于本地离线场景

    前言 上一篇文章介绍了使用SemanticKernel/C#的RAG简易实践,在上篇文章中我使用的是兼容OpenAI格式的在线API,但实际上会有很多本地离线的场景.今天跟大家介绍一下在Semanti ...

  8. 【Spring-Security】Re04 Matchers配置规则API

    一.使用antMatchers放行静态资源: package cn.zeal4j.configuration; import cn.zeal4j.handler.FarsAuthenticationF ...

  9. openAI的仿真环境Gym Retro的Python API接口

    如题,本文主要介绍仿真环境Gym Retro的Python API接口 . 官网地址: https://retro.readthedocs.io/en/latest/python.html ===== ...

  10. 不符合自身利益的科学讨论是否应该得到尊重—— 读《自家员工质疑Jeff Dean领衔的Nature论文被解雇,谷歌:我们彻查了,质疑不符合标准》有感

    读了一篇博文<自家员工质疑Jeff Dean领衔的Nature论文被解雇,谷歌:我们彻查了,质疑不符合标准>,其问大致是说Google提了一篇使用reinforcement learnin ...