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

news2024/9/20 6:20:31

前言

最近有个需求,是在浏览器插件中获取 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) return
    if (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) return
    if (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.coloradmin.cn/o/2106859.html

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

相关文章

【unplugin-vue-router】超级实用的自动路由,具体使用教程!

一、安装 vite 创建vue项目的时候选择 auto import 【推荐】 二、使用 原理:参考 vite 官网 来看一个简单的例子: 这是项目的pages目录结构 src/pages/ ├── index.vue ├── about.vue └── users/├── index.vue└── [id].vueunplugin-…

C语言08--指针数组结合

前言: 这次的指针数组结合乃作者呕心沥血之作,大家翻翻进度条就知道了,内容十分干货,各位读者若能全部耐心解析读懂了,想必也能理解掌握C语言中的数组指针这两把利剑了。 指针数组结合: 指针数组 概念&a…

异步编程学习

UniTask UniTask 访问UniTask的GitHub的主页可以直接下载unity Package进行导入,或者通过 Package Manager导入,导入完成之后根据文档加一下 宏定义“UNITASK_DOTWEEN_SUPPORT” 这样就可以正常的控制DoTween了 2.UniTask 的简单使用 // UniTask 是可以作…

lambda表达式用法——C#学习笔记

“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。 实例如下: 代码如下: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.…

景联文科技:专业视频标注服务助力计算机视觉应用升级

视频标注是指对视频内容进行分析,并在视频中的特定对象、行为或事件上添加标签的过程。 视频标注包括: 1. 对象检测与跟踪 •对象检测:在每一帧中识别并定位特定的对象,如人、车、动物等。 •对象跟踪:跟踪这些对象…

你知道吗?Python现在这么火爆的真相!

Python之所以如此火爆,主要得益于其多方面的优势和广泛的应用场景。以下是对Python火爆原因的详细归纳: 1. 易学易用 语法简洁:Python的语法设计非常简洁、直观,易于学习和理解。初学者能够快速上手,减少编写代码时的…

解决linux云服务器ping不通另一台linux云服务器的问题

这里以华为云服务器为例 1、找到云主机详情:xxx实例 / 实例概览 / 服务器详情,找到安全组 2、找到云主机当前在使用的安全组,添加入向规则 注意这里要选择 ICMP 协议,因为 ping 的协议是基于 ICMP 协议工作的 3、再次ping即可通 …

多目标应用:四种多目标优化算法(NSGA2、NSPSO、NSDBO、NSCOA)求解柔性作业车间调度问题(FJSP),MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题(Flexible Job Scheduling Problem, FJSP) 的描述如下:n个工件 { J , J 2 , . . , J n } \{J,J_2,..,J_n\} {J,J2​,..,Jn​}要在 m m m 台机器 { M 1 , M 2 , . . , M m } \{M_1,M_2,..,M_m\} {M1​,M2​,..,Mm​} …

linux基础IO——动静态库——实现与应用学习、原理深度解析

前言:本节内容是基础IO部分的动静态库。 本节内容, 我们将站在实现者的角度上自己实现一下动静态库, 并且会站在使用者的角度上使用我们自己实现的库。过程中牵扯到许多新的知识, 最后我们会重谈一下我们的进程。 理解一下有了动静…

【Python基础】想学好Python,就必须要知道的Python知识。一篇文章带你了解Python,学好Python!!!

Python知识涵盖面非常广泛,从基础语法到高级特性,再到丰富的库和框架,都是Python学习的重要组成部分。 一、基础语法 变量与数据类型: Python是动态类型语言,变量无需声明类型,直接赋值即可。常见的数据类…

织梦dedecms后台文章列表显示空白或有页码显示不了文章的解决方案

cms系统在用的过程才会发现更多的问题,dedecms也不例外。 问题描述: 可以正常登录,列表正常显示,文章页码也是正常,就是无法显示文章的标题。 分析原因: 1、是否改动源码 2、数据库是否完整 在数据库是…

非标独立设计选型--二十一--滚子链选型计算

链传动 相比于带传动 1、噪音大、震动大---平稳性不加、精度不够 运行速度不要太快…… 2、负载能力强,抗造---大负载、线性传动---抗冲击 【工况1】负载较大(几百kg---几吨)、运行速度较缓慢的场合 3、预紧力不需要像同步带那样大…

OpenAI 的发展启示录

OpenAI 的发展启示录 前言OpenAI 的发展启示录 前言 在当今科技迅猛发展的时代,人工智能(AI)正以前所未有的速度改变着我们的生活和工作方式。OpenAI 作为人工智能领域的先驱者,其发展路径和成就备受关注。它的每一次突破和创新&…

信也持续构建集群容器化改造之路

1. 前言 随着应用构建需求增加以及新构建场景引入,公司对构建系统的扩展性、稳定性要求日益提高。多语言构建(如Golang、Java、Python、Node.js 等)所依赖的环境,部署在同一台物理机上时,使构建机环境维护困难&#xf…

Elasticsearch Mapping 详解

1 概述 映射的基本概念 Mapping 也称之为映射,定义了 ES 的索引结构、字段类型、分词器等属性,是索引必不可少的组成部分。 ES 中的 mapping 有点类似与DB中“表结构”的概念,在 MySQL 中,表结构里包含了字段名称,字…

【gtokentool】元宇宙nft区块链是什么

元宇宙 元宇宙的定义 元宇宙(Metaverse)这个词起源于Neal Stephenson在1992年出版的小说《雪崩》,Metaverse由Meta(意即“超越”、“元”)和verse(意即“宇宙universe”)两个词构成。元宇宙是整…

安卓13带有系统签名的应用不能正常使用webview 调用webview失败 系统应用app apk

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 android版本高一些的平台,经常会遇到一些权限安全问题,像客户的应用如果带有系统签名,会导致不能正常使用webview问题。 2.问题分析 我们log信息,可以发现下面的提示: Fo…

权威解读|2024固定网国内数据传送业务办理指南

一、固定网国内数据传送业务是什么? 固定网国内数据传送业务,是指互联网数据传送业务以外的,在固定网中以有线方式提供的国内端到端数据传送业务。主要包括基于IP承载网、ATM网、X.25分组交换网、DDN网、帧中继网络的数据传送业务等。 根据…

佰朔资本:股票的买卖点有哪些?如何判断?

1、根据均线找买卖点 当股价跌破5日均线时,投资者可以将其作为卖点;股价向下跌触碰5日均线之后,出现反弹向上运转的痕迹,投资者可以将其作为买点。 2、根据MACD方针和KDJ方针找买卖点 当MACD方针或许KDJ 方针出现高位死叉时&am…

AI绘画神器 Fooocus 2.0 来啦!出图质量升级+新增4大实用功能!低配电脑必用的AI绘画工具教程

大家好,我是灵魂画师向阳 之前为大家推荐过一款融合了 midjourney 和 stable diffusion 优点的 AI 绘画工具 Fooocus,它用的是开源的 SDXL 1.0 模型,可以免费生成高质量的图像,同时操作界面又如 Midjourney 般简单,受…