写一个Chrome浏览器插件(manifest v3)

news2024/12/23 18:00:29

目录

1、创建manifest.json 文件

2、开始写popup页面以及对应的逻辑。

2.1 popup 页面

2.2 后台运行 background.js 

2.3 content.js 

2.4 popup页面的js文件

3、chrome 浏览器加载本项目

4、参考文档


1、创建manifest.json 文件

首先需要在项目的根目录下创建manifest.json文件,该文件描述插件的相关信息,如下所示:

  • description:插件的描述字段
  • name:插件的名字
  • manifest_version:chrome插件的版本(目前最新为版本3)
  • version:项目版本
  • author:项目作者
  • default_locale:默认为中文

icon图标,以及下面不同尺寸图标对应的路径信息。

 web可访问的资源路径,以及对应的匹配规则。

权限配置列表:

  • storage chrome 存储相关的权限。
  • tabs 浏览器标签页的权限
  • background 后台运行的权限
  • scripting 脚本执行的权限
  • contextMenus 右键菜单的权限
  • 其他一些权限......

本机权限:匹配所有

action 包括默认标题名,默认的icon,默认的popup对应的路径。

后台运行,service_worker对应的js文件路径。

content脚本包括:

  • matches 匹配的规则
  • js content 脚本的路径
  • all_frames 是否支持 iframe 修改。 

以上对应manifest.json 文件内容如下所示:

{    
      "description": "这是一个解密的工具",
      "name": "my_chrome_plug",
      "manifest_version": 3,
      "version": "1.0.0",
      "author": "yixuan",
      "default_locale": "zh_CN",
      "icons": {
        "16": "static/img/icon.png",
        "48": "static/img/icon.png",
        "128": "static/img/icon.png"
      },
      "web_accessible_resources": [{
        "resources": [
          "static/js/*",
          "static/css/*",
          "static/img/*"
        ],
        "matches": [
          "<all_urls>"
        ]
      }],
      "permissions": [
        "storage",
        "tabs",
        "background",
        "scripting",
        "contextMenus"
      ],
      "host_permissions": [
        "<all_urls>"
      ],
      "action": {
        "default_title": "my_chrome_plug",
        "default_icon": "static/img/icon.png",
        "default_popup": "index.html"
      },
      "background": {
        "service_worker": "static/js/background.js"
      },
      "content_scripts": [{
        "matches": [
          "<all_urls>"
        ],
        "js": [
          "static/js/content.js"
        ],
        "all_frames": true,
        "run_at": "document_idle"
      }]
    }
    

2、开始写popup页面以及对应的逻辑。

首先,列一下项目目录结构:

2.1 popup 页面

写一个解码的小工具,2个文本域输入框,和一个解码的按钮,对应页面html如下所示:

<body>
    <div class="_content">
        <form class="form-inline">
            <div class="form-group">
                <textarea type="text" class="from-control" id="_input" rows="6" placeholder="请输入......"></textarea>
            </div>
        </form>
        <div>
            <button id="_button" type="button" class="btn btn-primary"> 解码 </button>
        </div>
        <div class="form-group">
            <textarea type="text" class="from-control" id="_output" rows="16"></textarea>
        </div>
    </div>
</body>

2.2 后台运行 background.js 

本项目中写了2个功能:

  • 创建右键菜单,以及菜单点击事件逻辑
  • 监听对应消息事件

所对应的代码如下所示:

// 创建右键菜单
chrome.contextMenus.create({
    id: "parent",
    title: 'DECODE 解码',
    contexts: ['page']
})
// 监听右键菜单单击事件,创建的tab标签页,指向的页面为index.html
chrome.contextMenus.onClicked.addListener((info, tab) => {
    if(info.menuItemId == 'parent') {
        console.log('menu......');
        chrome.tabs.create({
            url: "index.html" 
        })
    }
})
// 消息监听
chrome.runtime.onMessage.addListener((message) => {
    let keyArrys = Object.keys(message);
    let valueArrays = Object.keys(message);
    keyArrys && keyArrys.map((res, index) => chrom.storage.local.set({[res] : valueArrays[index]}))
})

2.3 content.js 

content.js 和目标网页共享DOM节点,但是和目标的JS部分是隔离的,不能互相调用。

可以通过chrome api 对background.js 和 popup 页面的js部分进行通信,background.js 可以一直接受content.js发送过来的消息,因为background.js 一直在后台运行,而content.js 只有在popup页面打开的时候才能接收到对应的消息。

下面我们在content.js 中开始发送消息,如下所示:

async function sendMessage () {
    console.log("开始发送消息.............");
    await chrome.runtime.sendMessage(sessionStorage, function (res) {
        console.log("收到回复...............");
    })
}

2.4 popup页面的js文件

在当前js文件开始写对应的解码逻辑。首先,整个dom加载完毕之后,对解码按钮添加对应的点击事件,然后开始进行解码处理,包括对空格,单双引号等处理。

代码如下所示:

function decode () {
    try {
        var inputValue = $("#_input").val().trim();
        var reg = /^['|"](.*)['|"]/;
        var responseParams = true;
        if (inputValue.includes("helloword")) {
            inputValue = inputValue.replaceAll("helloworld", "");
            responseParams = false;
        }
        inputValue = inputValue.replace(reg, "$1");
        var output = DECODE(inputValue);
        responseParams && output.res && (output.res = JSON.parse(output.res))
        $("#_output").val(JSON.stringify(output))
    } catch (error) {
        console.log(error)
    }
}

document.addEventListener('DOMContentLoaded', () => {
    $("#_button").click(() => {
        decode()
    })
})

3、chrome 浏览器加载本项目

1、点击浏览器右上角->扩展程序->管理扩展程序,如下图所示:

2、点击右上角打开开发模式,然后单击“加载已解压的扩展程序”按钮,选择自己的项目目录即可。如下图所示:

3、点击浏览器右上角的本项目插件图标,弹出popup页面,在上面输入框中输入需要解码的内容,然后单击“解码”按钮,把对应解码的内容的输出到下面的输入框中,如下图所示:

4、插件右键菜单,鼠标在网页空白处,右键弹出菜单,可以看到自己创建的菜单以及icon,然后单击对应的菜单,浏览器将新建一个标签页面,指向自己配置的popup页面。如下如所示:

4、参考文档

其他一些配置或者示例可以参考以下文档:

chrome官方文档(英文版)

360中文开发文档

最好参考chrome 官方文档,360的文档,里面的内容并不是最新的,是manifest v2 版本,v3 和 v2 还是有一些差异的,在开发的时候注意以下manifest对应的版本。

 

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

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

相关文章

深入剖析Redis系列- Redis数据结构之哈希

1.11.5哈希类型(hash) Redis的hash 是一个string类型的key和value的映射表&#xff0c;这里的value是一系列的键值对&#xff0c;hash特别适合用于存储对象。 哈希类型的数据操作总的思想是通过key和field操作value&#xff0c;key是数据标识&#xff0c;field是域&#xff0c;…

基于SSM+Vue的舞蹈网站

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

大二上Redis学习笔记

redis非关系型数据库NOSQL&#xff0c;用c语言编写的,基于内存的数据库&#xff0c;每秒支持十几万的读写操作&#xff0c;性能远超数据库&#xff0c;还支持集群、分布式、主从同步等配置。 Redis基本功能 1 发布订阅系统 2 地图信息分析 3 计时器和计数器 redis运行的图形界…

【腾讯云TDSQL-C Serverless 产品体验】使用 Python向TDSQL-C添加读取数据实现词云图

关于TDSQL-C Serverless介绍 TDSQL-C 是腾讯云自主研发的新一代云原生关系型数据库。 它融合了传统数据库、云计算和新硬件技术的优势,100%兼容 MySQL,为用户提供具有极致弹性、高性能、高可用性、高可靠性和安全性的数据库服务。 TDSQL-C 实现了超过百万每秒的高吞吐量,支持…

SpringCloud 学习(四)Hystrix

6. Netflix.Hystrix 6.1 简介 ● 扇出 多服务之间调用&#xff0c;若微服务 A 调用微服务 B 和微服务 C&#xff0c;微服务 B 和 微服务 C 又调用其他微服务&#xff0c;这就是扇出 ● 服务雪崩 若扇出的链路上某个微服务的调用响应时间过长或者不可用&#xff0c;么此扇出…

ESP32在CAN(TWAI)波特率不同时收发数据,导致总线错误无法恢复

问题描述&#xff1a; 总线上有两个设备&#xff0c;主机&#xff1a;100ms周期发送数据。从机&#xff1a;以不同波特率发送数据&#xff0c;再把从机波特率调节至主机波特率一致无法通信。 环境&#xff1a;VSCODE IDF-v5.0 问题分析&#xff1a; 我们先看下ESP32技术参…

Spring 学习(四)注解实现自动装配及注解开发

1. 注解实现自动装配 JDK 1.5 开始支持注解&#xff0c;Spring 2.5 开始支持注解。 使用须知 导入约束 配置注解的支持&#xff08; <context:annotation-config/> &#xff09; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns&qu…

2023微信头像生成小程序,国庆头像生成,基于skyline+vue3+t

微信头像生成小程序&#xff0c;基于skylinevue3t该项目已适配微信小程序隐私政策&#xff0c;截图、获取头像等诸多新的接口 如何使用&#xff1a; 将代码导入到HBuilderX开发工具&#xff0c; 可无需修改任何代码&#xff0c;运行并编译到微信开发者工具 skyline需要使用微…

layui中使用JavaScript监听下拉框(select)的变化,根据选中的值来决定是否显示或隐藏input元素

HTML代码 <div class"layui-form-item" id"rubric"><label class"layui-form-label">前端说明</label><div class"layui-input-inline"><input type"text" id"user_rubric" name"…

页面添加遮罩层

1.css代码 // 子绝父相.self-check-tag {display: inline-block;min-width: 132px;height: 32px;position: relative;.overlay {position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: gray;opacity: 0.1;}2.效果

QT windows dpi变化导致的界面异常处理

问题&#xff1a;已经在UI界面中利用布局设计好界面&#xff0c;但是运行程序后显示的界面出现错乱&#xff0c;而且在做出一些修改后重新构建&#xff0c;运行时界面无变化。 目录 一、解决UI设计界面与运行时显示界面不一致的问题 1、导致该现象的原因有&#xff1a;显示屏…

[Linux] 3.Linux下编码和执行文件

Ctrl Alt T快捷键调出命令终端 输入xrandr指令把现有的电脑分辨率列出来 &#xff0c;xrandr -s 分辨率可以调节至想要的分辨率 调节字体大小&#xff1a;Ctrl Shift “”或Ctrl Shift “-” 使字体变大变小 拖动窗口右下角可调节窗口大小 Ctrl “L”清屏 编写C代码文件:…

【数据结构】散列表(哈希表)的学习知识总结

目录 1、散列表 2、散列函数 2.1 定义 2.2 散列函数的构造 2.2.1 除留余数法 2.2.2 直接定址法 2.2.3 数字分析法 2.2.4 平方取中法 3、冲突&#xff08;碰撞&#xff09; 4、处理冲突的方法 4.1 拉链法&#xff08;链接法&#xff09; 4.2 开放定址法 5、C语言…

电缆直埋、电缆沟、电缆井大样图

一、图纸下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1_SUnhFHMUY8Q_kkhgzscDQ?pwd8888 提取码&#xff1a;8888 二、部分图纸预览

GoogLeNet网络

目录 1. 创新点 1.1 引入Inception结构 1.2 11卷积降维 1.3 两个辅助分类器 1.4 丢弃全连接层&#xff0c;使用平均池化层 2. 网络结构 3. 知识点 3.1 torch.cat 3.2 关于self.training 3.3 关于load_state_dict中的strict 4. 代码 4.1 model.py 4.2 train.py …

MQ - 30 基础功能:死信队列的设计

文章目录 导图概述什么是死信队列死信队列实现的技术方案死信队列的存储目标死信队列的方案设计生产死信队列消费死信队列Broker 的死信队列主流消息队列的死信功能RocketMQRabbitMQ总结导图 概述 在日常业务的消费数据过程中,如果遇到数据无法被正确处理,就需要先手动把消息…

202309解决新版Animate Diff报错问题

在安装最新版的Animate Diff的时候发现报错了 ImportError: cannot import name images_tensor_to_samples from modules.sd_samplers_common (W:\A1111\stable-diffusion-webui\modules\sd_samplers_common.py)原因很简单&#xff0c;Animate diff已经适配了新版webui1.6 所以…

基于LQR算法的一阶倒立摆控制

1. 一阶倒立摆建模 2. 数学模型 倒立摆的受力分析网上有很多&#xff0c;这里就不再叙述。直接放线性化后的方程&#xff1a; F (Mm)x″-mLφ″ (ImL)φ″ mLx″ mgLφ&#xff08;F为外力&#xff0c;x为物块位移&#xff0c;M&#xff0c;m为物块和摆杆的质量&#xff0c;…

计算机是怎么跑起来的(2)?程序如何驱动硬件工作的?

上文计算机是怎么跑起来的?从零开始手动组装微型计算机我们说了&#xff0c;如何手动从来组装一台计算机&#xff0c;那组装完后的计算机上是怎么跑起来程序的呢&#xff1f;程序是如何驱动硬件工作的&#xff1f; 前面我们通过DMA将代码输入到内存的指定位置&#xff0c;然后…

JavaWeb 学习

1. 基本概念 1.1 Web web&#xff1a;网络&#xff0c;网页 静态 web html&#xff0c;css提供给所有人看的数据始终不会变化 动态 web 淘宝提供给每个人看的数据会有所不同技术栈&#xff1a;Servlet/JSP&#xff0c;ASP&#xff0c;PHP Java 中&#xff0c;动态 web 资…