前言

最近有个需求,是在浏览器插件中获取 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. 如何巧妙使用some函数来优化性能

    什么时候会用的array.some? 需要从数组里快速找到符合条件的某一项  如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测.   如果没有满足条件的元素,则返回false ...

  2. 用这开源小书学 Docker,香!

    > 最新.全面.通俗.可多端阅读的 Docker 教程小书.>> 编程导航开源仓库:https://github.com/liyupi/code-navDocker 可以说是一个改变 ...

  3. [oeasy]python0132_[专业选修]utf-8_unicode_transformation_format_8_编码方式

    utf-8 回忆上次内容 上次再次输出了大红心<span style="color:red"></span> 找到了红心对应的编码 黑红梅方都对应有编码   ...

  4. c++17 using继承所有构造函数

    //使用using继承所有的构造函数 #include "tmp.h" #include <iostream> using namespace std; struct ...

  5. scratch源码下载 | 超大太空游戏【80MB】

    按方向键或AWSD键控制角色移动,按空格键或X键攻击. 程序超级大,共80MB,耐心等待加载. 截图: 点击下载源码 更多源码访问:小虎鲸scratch资源站

  6. adb对安卓app进行抓包(ip连接设备)

    adb对安卓app进行抓包(ip连接设备) 一,首先将安卓设备的开发者模式打开,提示允许adb调试 二,自己的笔记本要和安卓设备在同一个网段下(同连一个WiFi就可以了) 三,在笔记本上根据ip来连接 ...

  7. 将txt转化为csv的方法和遇到问题

    一.无法修改扩展名步骤如下 二.转换之后所有数据都挤在第一列 win10系统修改文件扩展名只需4部,打开我的电脑->查看->选择->查看->取消勾选(已知隐藏文件的扩展名)-& ...

  8. Jmeter循环控制器

    循环控制器(Loop Controller),循环控制器会将该控制器里面所有请求循环运行指定次数 循环次数:勾选"永远"则程序会一直循环运行不会停止,不勾选"永远&quo ...

  9. Jmeter参数化4-数据库数据引入

    1. 下载jmeter依赖的mysql驱动包 jmeter要连接mysql数据库,首先得下载mysql驱动包.执行"select version()"查看数据库版本 mysql历史 ...

  10. 【Vue】el-table 简易表格可筛选列

    需求实现: 代码逻辑: 按钮控件: <el-popover placement="top-start"> <el-checkbox-group v-model=& ...