当前位置: 首页 > article >正文

chrome 插件开发入门

1. 介绍

Chrome 插件可用于在谷歌浏览器上控制当前页面的一些操作,可自主控制网页,提升效率。

平常我们可在谷歌应用商店中下载谷歌插件来增强浏览器功能,作为开发者,我们也可以自己开发一个浏览器插件来配合我们的日常学习工作,提升幸福感。

在谷歌插件开发者官网,可以阅读插件开发文档来写插件,插件开发主要是 JavaScript,因此对前端开发者很友好

2. 快速入门

2.1 manifest.json 配置

  1. 新建一个文件夹,就叫 ChromePlugin

  2. 在 ChromePlugin 根目录下新建 manifest.json 文件

manifest 文件是插件的配置文件,只有在该 json 文件中增加了配置项,才允许增加自定义的内容,下面是常见的 json 文件配置

{
    "manifest_version": 3,
    "name": "chromePlugin",
    "version": "1.0.0",
    "description": "我的第一个谷歌插件",
    "icons": {
        "16": "./assets/images/icon16.png",
        "32": "./assets/images/icon32.png",
        "48": "./assets/images/icon48.png",
        "128": "./assets/images/icon128.png"
    },   
}

基本配置:

  • manifest_version:manifest 的版本,是谷歌针对插件开发的版本配置,目前主流都是 3 版本,2 版本已经停止更新
  • name:插件的名称,即插件在谷歌商店以及使用时的名称
  • version:插件的版本
  • description:插件的描述信息
  • icons:描述插件图标的大小和文件路径,目前提供 4 种规格的图片,按照上述配置分别传入不同大小的图片即可,图片地址可在根目录下创建一个 assets文件放置静态资源

其他配置可见下文中的详细解释

到这里,一个 chrome 插件已经可以被加载出来了

打开谷歌浏览器,输入 chrome://extensions ,启用开发者模式(右上角),再点击「加载已解压的扩展程序」然后找到 ChromePlugin 这个文件夹打开,便可以将这个插件加载进来了,只不过当前插件没有任何功能,所以也是灰色的

Image Image

2.2 action 配置

在 manifest.json 中除了上述的基础配置外,还可配置 action,action 字面上意思就是我们点击右上角的插件图标时的反应,比如打开一个交互面板等等。这种交互的集合就是 action。

首先先在 manifest.json 中配置 action,可见官网针对 action 的配置信息,action配置。

default_popup 可在点击插件图片时弹出一个弹层,弹层的内容就是 default_popup 所对应的 html 文件。

{
    "manifest_version": 3,
    "name": "chromePlugin",
    "version": "1.0.0",
    "description": "我的第一个谷歌插件",
    "icons": {
        "16": "./assets/images/icon16.png",
        "32": "./assets/images/icon32.png",
        "48": "./assets/images/icon48.png",
        "128": "./assets/images/icon128.png"
    },
    "action": {
        "default_title": "Click Me",
        "default_popup": "./action/index.html",
        "default_icon": "./assets/images/icon32.png"
    }    
}

可在根目录下新建一个 action 文件夹,然后再创建一个 index.html 文件,写一个简单的测试文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .hello {
            width: 100px;
        }
    </style>
</head>
<body>
    <div class="hello">hello simon</div>
  	<script src="./index.js"></script>
</body>
</html>

再次加载该插件,点击插件图标,可在图标下方看到一个弹层,弹层显示的是 html 文件中的内容

Image

如果想写 js 代码,不能直接在 html 中创建一个 script 标签,然后写代码,插件中不允许 html 中有内联脚本,因此需要将脚本代码作为一个单独的文件,再通过 script 标签来引入

2.3 content_scripts

如果我们想给插件添加功能,那就需要再配置 content_scripts(内容脚本),插件content_scripts。

不是所有的 chrome 的 api 方法都能在 content_scripts 中使用

content_scripts 的特性:

  • 可在页面打开、或页面加载结束、或者页面空闲时注入

  • 共享页面的 dom,因此脚本文件可以操作页面上的 dom

  • JS 隔离,脚本文件的 js 不会影响到页面中的 js,也无法引用页面 js 中的函数或变量

content_scripts 的注入方式也有多种:静态注入、动态注入、编码注入

  • 静态注入,即在 manifest.json 文件中指定 content_scripts 中的 js 文件,比较常用
  • 动态注入,通过 chrome.scripting.registerContentScripts 方法注入
  • 编码注入,通过 chrome.scripting.executeScript

在 manifest.json 中可传入的属性

属性类型描述
matches字符串数组必填,指定将内容脚本注入到哪些网页
css字符串数组可选,要注入到匹配页面的 css 文件
js字符串数组可选,要注入到匹配页面的 js 文件
run_atdocument_start
|document_end
|document_idle
可选,指定何时将脚本注入到网页中,默认值document_idle
document_idle: 页面空闲时
document_end:在dom完成之后,图片等资源加载前注入脚本
document_start:在dom完成前就注入脚本

在 manifest.json 中配置 content_scripts

{
    "manifest_version": 3,
    "name": "chromePlugin",
    "version": "1.0.0",
    "description": "我的第一个谷歌插件",
    "icons": {
        "16": "./assets/images/icon16.png",
        "32": "./assets/images/icon32.png",
        "48": "./assets/images/icon48.png",
        "128": "./assets/images/icon128.png"
    },
    "action": {
        "default_title": "Click Me",
        "default_popup": "./action/index.html",
        "default_icon": "./assets/images/icon32.png"
    }, 
    "content_scripts": [
      {
        "matches": ["https://*/*"],
        "css": ["./src/index.css"],
        "js": ["./src/main.js"]
      }
    ]
}
// 计算图片大小
function getByte(src){
    return fetch(src).then(function(res){
        return res.blob()
      }).then(function(data){
        return (data.size/(1024)).toFixed(2)+'kB';
      })
}
// 在页面上的图片的title属性上显示出来
function showInfo(el,byte){
    const html=`真实尺寸:${el.naturalWidth}*${el.naturalHeight}\n显示尺寸:${el.width}*${el.height}\n存储大小:${byte}`;
    el.title=html;
}
document.addEventListener('mouseover',function(e){
    //移动到图片元素上时、则显示信息
    if(e.target.tagName=='IMG'){
        getByte(e.target.src).then(byte=>{
            showInfo(e.target,byte)
        });
    }
},true)

2.4 background

配置后台脚本,用于处理插件的主要事件的处理,后台脚本指定了属性 service_worker,其实后台脚本是 Service Worker 上处理的。我们插件上的一些主要逻辑的处理都可以放到这个脚本文件中

{
    "manifest_version": 3,
    "name": "chromePlugin",
    "version": "1.0.0",
    "description": "我的第一个谷歌插件",
    "icons": {
        "16": "./assets/images/icon16.png",
        "32": "./assets/images/icon32.png",
        "48": "./assets/images/icon48.png",
        "128": "./assets/images/icon128.png"
    },
    "action": {
        "default_title": "Click Me",
        "default_popup": "./action/index.html",
        "default_icon": "./assets/images/icon32.png"
    }, 
    "content_scripts": [
      {
        "matches": ["https://*/*"],
        "css": ["./src/index.css"],
        "js": ["./src/main.js"]
      }
    ],
  	"background": {
        "service_worker": "./src/server_worker.js"
    }
}

2.5 右键菜单

当我们点击鼠标右键时,可打开一个菜单,其中有复制粘贴等功能,插件也可以自定义右键的菜单,同样需要在 manifest.json 中添加权限配置

{
    "manifest_version": 3,
    "name": "chromePlugin",
    "version": "1.0.0",
    "description": "我的第一个谷歌插件",
    "icons": {
        "16": "./assets/images/icon16.png",
        "32": "./assets/images/icon32.png",
        "48": "./assets/images/icon48.png",
        "128": "./assets/images/icon128.png"
    },
    "action": {
        "default_title": "Click Me",
        "default_popup": "./action/index.html",
        "default_icon": "./assets/images/icon32.png"
    }, 
    "content_scripts": [
      {
        "matches": ["https://*/*"],
        "css": ["./src/index.css"],
        "js": ["./src/main.js"]
      }
    ],
  	"permissions": ["contextMenus"]
}

permissions 是允许增加权限配置,右键菜单就是一种权限配置,开启右键菜单权限后,需要再通过代码新增右键的菜单,这个时候就需要用到上一步的 background 中的配置了

在 service_worker.js 文件中新增一个右键菜单,可使用 chrome.contextMenus.create 方法来创建

chrome.contextMenus.create({
    type: 'normal',
    title: '插件的右键菜单',
    contexts:['all'],
    id:'menu-1'
});

保存后,就能在右键看到一个菜单选项了

2.6 permissions

在上一步创建的右键菜单中,涉及到权限设置,只有在 permissions 添加了对应权限后,才允许去创建菜单,权限除了右键菜单外,还有其他的权限,权限列表,常见的有:

  • audio: chrome.audio,控制连接到系统的音频设备
  • bookmarks: chrome.bookmarks,读取和更改书签的权限
  • clipboardRead:通过 clipboard API 读取剪切板上的数据去粘贴
  • clipboardWrite: 通过 clipboard API 剪切内容并复制到剪切板
  • contextMenus: chrome.contextMenus 控制右键菜单的权限
  • cookies: chrome.cookies 查询和更改 cookies 的权限
  • desktopCapture: chrome.desktopCapture 截取屏幕内容的权限
  • downloads: chrome.downloads 管理下载内容的权限
  • favicon:通过 Favicon 读取网站页面的图标的权限
  • history: chrome.history 读取和更改浏览记录的权限
  • idle: chrome.idle 读取浏览器是否处于空闲状态的权限
  • proxy: chrome.proxy 管理浏览器的代理设置
  • sidePanel:chrome.sidePanel 打开侧边栏的权限
  • storage: chrome.storage 存储、检索和跟踪用户数据的更改的权限
  • system.cpu: chrome.system.cpu,查询 CPU 数据的权限
  • system.memory: chrome.system.memory,获取物理内存的权限

当涉及到权限问题时,就需要先在 permissions 添加了对应权限后,才允许使用 chrome.xxx 再使用对应的功能。

2.7 options

options 就是选项页面,可用于在插件的右键选项中进行配置跳转,也可以在插件管理页面点击详情后打开插件选项,当增加该配置项后,选中插件再右键时,会增加一个「选项」的菜单,点击后会跳转到配置的页面。要展示该选项需要在 manifest.json 中配置 options_ui

{
    "manifest_version": 3,
    "name": "chromePlugin",
    "version": "1.0.0",
    "description": "我的第一个谷歌插件",
    "icons": {
        "16": "./assets/images/icon16.png",
        "32": "./assets/images/icon32.png",
        "48": "./assets/images/icon48.png",
        "128": "./assets/images/icon128.png"
    },
    "action": {
        "default_title": "Click Me",
        "default_popup": "./action/index.html",
        "default_icon": "./assets/images/icon32.png"
    }, 
    "content_scripts": [
      {
        "matches": ["https://*/*"],
        "css": ["./src/index.css"],
        "js": ["./src/main.js"]
      }
    ],
  	"permissions": ["contextMenus"],
  	"options_page": "./options/index.html", // chrome40 之前的写法
  	"options_ui": { // chrome40 之后的写法
      "page": "./options/index.html",
      "chrome_style": true // 添加一些默认样式
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>这是 options 点击后打开的页面</div>
</body>
</html>

3. 页面通信

在 manifest.json 中可通过不同配置来实现插件的扩展能力,比如 content_scripts、background、options、actions 都有脚本文件,那如何在不同的脚本文件中传递数据呢,比如在 content_scripts 是在网页中运行的,其中的数据如何共享给 background,可以通过页面通信来传递数据。

官网文档

3.1 发送数据

// 从内容脚本 content_scripts 发送数据到扩展页面(background、options、actions)
(async () => {
  const response = await chrome.runtime.sendMessage({greeting: "hello"});
  console.log(response);
})();
// 从扩展页面(background、options、actions) 发送数据到内容脚本(content_scripts)
(async () => {
    // 需要先获取当前的tab页面
  const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
  const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"});
  console.log(response);
})();

不同的发送方,发送数据的方式也是不同的,在使用时需要有所区别

3.2 接收数据

接收数据的方式是一致的,都是通过 chrome.runtime.onMessage

// 接收数据
chrome.runtime.onMessage.addListener(
  (request, sender, sendResponse) => {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting === "hello")
      //处理完消息后、通知发送方
      sendResponse({farewell: "goodbye"});
  }
);

http://www.kler.cn/a/294019.html

相关文章:

  • 字节、快手、Vidu“打野”升级,AI视频小步快跑
  • 【网络工程】计算机硬件概述
  • 工业相机选取
  • Rust 建造者模式
  • learn-F12 Performance(性能)前端性能分析(LCP,CLS,INP)
  • 红日靶机(七)笔记
  • HTML <input> accept 属性
  • MQTT broker搭建并用SSL加密
  • 免费SSL证书怎么申请?
  • C#索引器(Indexer)
  • 排序算法(冒泡排序,选择排序,插入排序,快速排序)
  • 图片隐写方法
  • 使用c++创建WMI应用程序
  • Llama 3.1大模型的预训练和后训练范式解析
  • 【如何有效率地阅读源码】
  • 搜维尔科技:蹦床、跳绳或骑马,OptiTrack可以捕捉难以想象的物体
  • Tensorflow2 如何扩展现有数据集(缩放、随机旋转、水平翻转、平移等),从而提高模型的准确率 -- Tensorflow自学笔记14
  • vscode安装使用plantuml插件
  • 从监控到智能:EasyCVR视频汇聚平台助力加油站安全监管升级转型
  • 网络安全服务基础Windows--第13节-加密技术
  • git的简单学习
  • 苹果系统(MacOS)资源管理器和终端的来回切换
  • ICM20948 DMP代码详解(5)
  • Vue eslint 语法检测问题
  • 水晶连连看 - 无限版软件操作说明书
  • 硬件工程师笔试面试知识器件篇——电感