如何开发一个浏览器插件

参考文章

Chrome 平台 API

一天学会Chrome插件开发

30分钟开发一款抓取网站图片资源的浏览器插件

manifest.json参数详解

Content Security Policy 入门教程

参考源码

github地址:一款提取网页图片数据的浏览器插件

秒杀插件(seckill)

一个chrome插件包含哪些文件及文件夹

D:.
│  manifest.json
│
├─html
│      index.html
│
├─images
│      icon-128.png
│      icon-16.png
│
├─scripts
│      background.js
│
├─styles
│      main.css
│
└─_locales
    ├─en
    │      messages.json
    │
    └─zh_CN
            messages.json

简单说明一下:

html:存放html页面
images:存放插件图标
scripts:存放js文件
styles: 存放样式
_locales: 存放多语言文件
manifest.json:用来配置所有和插件相关的配置,作为chrome入口文件,必须放在根目录

看目录结构,像不像一个网站?Bingo! Chrome插件就是一个网站类的应用,它是用html、javascript、css组成的一个webapp; 相比于通常的webapp, Chrome插件还可以调用更多浏览器层面的api,包括书签、历史记录、网络请求拦截、截获用户输入等等。(PS:插件不要随便乱装哦,很危险滴!)。

要想开发一款浏览器插件,必修有manifest.json文件

重要配置说明

manifest.json

如前所述,它包含了一些插件的元数据,作为chrome的入口文件,可以理解为插件的程序清单,那么它到底做了什么事情呢? 结合示例,我们细细来看:


{
     
    // 清单版本号,建议使用 版本 2,版本 1 是旧的,已弃用,不建议使用
    "manifest_version": 2,
    "name": "chome-plugin", // 插件名称
    "version": "1.8.6", // 插件版本
    // 这里写些废话,举个栗子,‘应产品要求,杀个程序祭天’
    "description": "This is an extension for your chrome",
    "icons":
    {
     
        "16": "images/custom/16x16.png",
        "48": "images/custom/48x48.png",
        "128": "images/custom/128x128.png"
    },
    //browser_action和page_action只能添加一个
    "browser_action":
    {
      //浏览器级别行为,所有页面均生效
        "default_icon": "images/custom/16x16.png", //图标的图片
        "default_title": "Hello ELSE", //鼠标移到图标显示的文字
        "default_popup": "html/popup.html" //单击图标后弹窗页面
    },
    "page_action":
    {
      //页面级别的行为,只在特定页面下生效
        "default_icon":
        {
     
            "24": "images/custom/24x24.png",
            "38": "images/custom/38x38.png"
        },
        "default_popup": "html/popup.html",
        "default_title": "Hello ELSE"
    },

    // 可选
    "author": "ELSE TEAM",
    "automation": "...",
    // 背景页的脚本路径,一般为插件目录的相对地址
    "background":
    {
     
        "scripts": [
            "scripts/background.js",
            "scripts/devtools-page.js"
        ]
    },
    "devtools_page": "html/devtools-page.html",

    // 内容脚本一般植入会被植入到页面中, 并且可以控制页面中的dom.
    "content_scripts": [
        {
     
            "js": ["js/else-insert.js"],
            "css": ["css/else-insert.css"],
            "matches": [""]// 被植入到页面,只在这些站点下 content_scripts会运行
        }
    ],
    // 数组,声明插件所需要的权限,这里就是很危险的存在了,想干坏事的你是不是很激动!
    "permissions": [
        "cookies", // 使用cookies
        "webRequest", //使用web请求
        "http://*", //可以通过executeScript或者insertCSS访问的网站地址。如: https://*.google.com/
        "management", //
        "storage", //使用本地存储
        "tabs", //操作标签
        "contextMenus" //右键菜单
    ]
    "default_locale ": "zh_CN" //默认语言(比如"zh_CN")
}

更详细的请看 manifest.json参数详解

content-scripts

内容脚本一般植入会被植入到页面中, 并且可以控制页面中的dom. 我们可以利用它实现屏蔽网页广告, 定制页面皮肤等操作. 在manifest.json中的基本配置如下:

{
     
    "content_scripts": [{
     
    "matches": [
        "http://*/*",
        "https://*/*"
    ],
    "js": [
        "lib/jquery3.4.min.js",
        "content_script.js"
    ],
    "css": ["base.css"]
  }],
}

以上代码中我们定义了content_scripts允许注入的页面范围, 插入页面的js以及css, 这样我们就能轻松改变某一个页面的样式.比如我们可以在页面中注入一个按钮:

如何开发一个浏览器插件_第1张图片
popup

popup是用户点击插件图标时打开的一个小窗口,当失去焦点后窗口就立即关闭,我们一般用它来处理一些简单的用户交互和插件说明。

由于popup窗口也是一个网页,所以我们一般会建立一个popup.html和popup.js用来控制popup的页面展示和交互.我们在manifest.json中配置如下:

{
     
    "page_action": {
     
        "default_title": "小夕图片提取插件",
        "default_popup": "popup.html"
  },
}

这里要注意一点的是,我们在popup.html中不能直接使用script脚本,需要用引入脚本文件的方式.如下:


<html>
  <head>
    <title>在线图片提取工具title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  head>
  <body>
    <div class="pop-wrap">
    div>
    <script src="lib/jquery3.4.min.js">script>
    <script src="popup.js">script>
  body>
html>

如下:
如何开发一个浏览器插件_第2张图片

background.js

background页面主要用来提供一些全局配置, 事件监听, 业务转发等.举几个常用案例:

1,定义右键菜单

,background.js 文件

const systems =
{
     
    a: '趣谈前端',
    b: '掘金',
    c: '微信'
}
// 谷歌浏览器加载监听事件
chrome.runtime.onInstalled.addListener(function (){
     
    for (let key of Object.keys(systems)){
     
    	// 上下文菜单
        chrome.contextMenus.create({
     
            id: key,
            title: systems[key],
            type: 'normal',
            contexts: ['selection'],
        });
    }
});

manifest.json 添加 右键菜单 权限

{
     
    "permissions": ["contextMenus"]
}

效果如下:
如何开发一个浏览器插件_第3张图片

加载并运行插件

在您的浏览器中访问 chrome://extensions 或者 浏览器 --> 设置 --> 更多工具 --> 扩展程序 进入扩展程序管理页面。
如何开发一个浏览器插件_第4张图片

通信机制

对于一个相对复杂的浏览器插件来说,我们不仅仅只操作dom或者提供基本的功能就行了,我们还需要向第三方或者自己的服务器抓取有用的页面数据,这个时候就需要用到插件的通信机制了.

因为content_script脚本存在于当前页面,受同源策略影响,导致我们无法将捕获到的数据传给第三方平台或者自己的服务器, 所以我们需要基于浏览器的通信API.一下是谷歌浏览器插件的通信流程:
如何开发一个浏览器插件_第5张图片

popup和background相互通信

由官方文档可知popup可以直接访问background页的方法,所以popup可以直接与其通信:

background.js

var getData = (data) =>{
     
    console.log('拿到数据:' + data)
}

popup.js

let bgObj = chrome.extension.getBackgroundPage();
bgObj.getData(); // 访问bg的函数

popup或者background页和content_script通信

1,使用chrome的tabs API进行消息通知

参数请看 chrome.tabs

popup.js : 发送消息给content_script和接收消息

// 给当前标签页的 content_script 发送消息给
chrome.tabs.query({
      active: true, currentWindow: true}, function (tabs){
     
	    chrome.tabs.sendMessage(tabs[0].id, "activeBtn", function (response){
     
	        console.log(response);
	    });
	}
);

// 接收消息
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
     
    console.log(sender.tab ?
        "from a content script:" + sender.tab.url :
        "from the extension");
    if (request.greeting == "hello")
        sendResponse({
     farewell: "goodbye"});
});

content_script接收和发送消息:

// 接收消息
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse){
     
    if (message == "activeBtn"){
     
        // ...
        sendResponse( {
     
            farewell: "激活成功"
        });
    }
});

// 主动发送消息
chrome.runtime.sendMessage({
     greeting: "hello"}, function (response){
     
    console.log(response, document.body);
    // document.body.style.backgroundColor="orange"
});

2,采用如下方式进行长连接

content_script.js

var port = chrome.runtime.connect( {
     
        name: "徐小夕"
    });
port.postMessage({
     
    Ling: "你好"
});
port.onMessage.addListener(function (msg)
{
     
    if (msg.question == "你是做什么滴?")
        port.postMessage({
     
            answer: "搬砖"
        } );
    else if (msg.question == "搬砖有钱吗?")
        port.postMessage( {
     
            answer: "木有"
        } );
});

popup.js

chrome.runtime.onConnect.addListener(function (port){
     
    port.onMessage.addListener(function (msg){
     
        if (msg.Ling == "你好")
            port.postMessage({
     
                question: "你是做什么滴?"
            });
        else if (msg.answer == "搬砖")
            port.postMessage({
     
                question: "搬砖有钱吗?"
            });
        else if (msg.answer == "木有")
            port.postMessage({
     
                question: "太难了."
            } );
    });
});

3,数据存储传递消息

chrome.storage用来针对插件全局进行数据存储,我们在任何一个页面(popup或content_script或background)下存储了数据,我们在以上三个页面都可以获取到, 具体用法如下:

获取数据
chrome.storage.sync.get('imgArr', function (data){
     
    console.log(data)
});
// 保存数据
chrome.storage.sync.set({
     'imgArr': imgArr}, function (){
     
    console.log('保存成功');
});

// 另一种方式
chrome.storage.local.set({
     key: value}, function (){
     
    console.log('Value is set to ' + value);
});

作者:徐小夕
链接:https://www.imooc.com/article/303109
来源:慕课网
本文大部分内容首次发布于慕课网

你可能感兴趣的:(js,javascript,js,web)