前端拓展:如何开发一个 Chrome 插件?

manifest_version:代表了manifest文件的版本,浏览器会根据这个值去指定该版本拥有的功能。

name:插件的名称。

version:插件版本。

将manifest.json文件放到一个文件夹内。

chrome://extensions/

在浏览器地址栏输入chrome://extensions/打开“拓展程序”页面。

注意:需要启用右上角的 “开发者模式” 才能加载已解压的插件文件:

加载已解压的插件

启用之后点击加载已解压的拓展程序,选择刚刚我们放入了manifest.json的文件夹,之后你会看到:

新增了一个我们刚刚添加的插件,而且浏览器右上角也会有我们的一个图标:

此时已经加载了一个插件了,但是这个插件除了占用浏览器的一个位置除外,没有任何作用。

如果没有设置插件图标,那么插件的第一个字符会成为插件的默认icon。

让插件看起来更“插件”一点

为了让这个插件更“完善”一点,我们给它加一个icon和描述,并且点击出现一个popup页面,popup 页面一般用来承载临时性的交互,且生命周期很短:单击图标打开popup,焦点离开又立即关闭,可以通过default_popup字段来定义。

{

“description”: “这是一段描述”,

// 插件管理页面的icon

“icons”: {

“84”: “./icon/ball.png”

},

// 浏览器右上角的图标和内容

“browser_action”: {

“default_icon”: “./icon/ball.png”,

“default_title”: “我的插件”,

“default_popup”: “./html/popup.html”

}

}

此时我们的目录结构也变成了这样:

给popup.html加上内容:

my-plugin

hello world!!

之后,我们点击插件右下角的“刷新”按钮:

你会发现插件有了icon和描述:

并且右上角的icon也变了,点击一下,会弹出我们刚刚编写的popup.html页面:

现在,我们一个“完整”的插件就已经做好了。

manifest.json 配置介绍


background

{

“background”: {

// 提供一个页面给background

“page”: “./html/background.html”

// 或者若干个js文件,后台会默认生成一个空白的html

“scripts”: [“./js/background.js”]

}

}

background配置项,为插件的后台常驻页面,生命周期随着浏览器的生命周期一样,浏览器一启动,后台页面就会开始运行,直到浏览器被关闭;或者在插件管理页面,将该插件禁用了,后台页面也会停止运行。

另外,background拥有的权限比较高,几乎可以调用所有的Chrome扩展API(除了devtools),同时拥有直接跨域的能力。

page:指定一个网页为后台页面。

scripts:指定若干个js文件,后台会自动生成一个html,并按顺序调用这些js文件。

注意:pagescripts 选项只能二选一,不然会报错。

配置好之后,属性插件,会出现一个背景页选项:

我使用的是一个background.js文件:

function _back() {

console.log(‘background.js’)

}

console.log(‘running…’)

点进去看看里面装的什么玩意:

没错,是一个普通的后台页面,如果background.js和其他页面有通信,则可以在这里进行查看请求或者调试代码。

如果使用page选项,打开也是这个样子。

另外:由于background是一直在后台运行的,为了优化性能,可以增加一个配置:

{

“background”: {

“persistent”: false

}

}

这样,插件就会在被需要时加载,在空闲时被关闭。比如安装、更新插件的时候,或者有其他页面与background通信的时候才会被加载。

content-scripts

content-scripts能够在合适的时机(页面载入前、载入后、空闲时)注入脚本,允许内容脚本更改其JavaScript环境,而不与页面或其他内容脚本发生冲突。

例如,原页面有个按钮,并且给按钮添加了一个点击事件:

click me

在content-scripts中,加入以下代码:

var greeting = "hola, ";

var button = document.getElementById(“mybutton”);

button.person_name = “Roberto”;

button.addEventListener(“click”, function() {

alert(greeting + button.person_name + “.”);

}, false);

当页面运行之后,脚本内容也会在插件定义的时间运行,当页面点击按钮时,会出现两次弹窗。

content-scripts配置:

{

“content_scripts”: [

{

// 在匹配的URL中运行,<all_urls>表示所有的URL都会运行。

“matches”: [“<all_urls>”],

// 注入的js,会按顺序运行。

“js”: [“./js/content.js”],

// css引入需谨慎,因为可能会影响全局的样式,同样也能接收多个css文件,会按顺序插入到页面中

“css”: [“./css/style.css”],

// 代码注入的时机,可选值: “document_start”, “document_end”, or “document_idle”,最后一个表示页面空闲时,默认document_idle

“run_at”: “document_start”

},

{

“matches”: [“https://www.baidu.com/”],

“js”: [“./js/other.js”],

“run_at”: “document_start”

}

],

}

content.js代码如下:

console.log(‘hello, from content.js’);

other.js代码如下:

console.log(‘hello, from other.js…’)

更新插件,当在 https://bytedance.feishu.cn/drive/home/运行时:

因为【 https://bytedance.feishu.cn/drive/home/】只匹配到了<all_urls>的规则,所以之后运行content.js

当在https://www.baidu.com/运行时:

同时命中了2个规则,所以content.js和other.js都会运行,顺序也是正确的。

content-scripts 和原始页面共享DOM,但是不共享JS,如要访问页面JS(例如某个JS变量),只能通过inject-scripts来实现。content-scripts能够访问的Chrome API的权限也比较低,只能访问以下四个API:

  • chrome.extension(getURL , inIncognitoContext , lastError , onRequest , sendRequest)

  • chrome.i18n

  • chrome.runtime(connect , getManifest , getURL , id , onConnect , onMessage , sendMessage)

  • chrome.storage

Inject-scripts

inject-scripts 是通过DOM操作插入的JS代码,通常在content-scripts只能操作DOM,但是却无法访问页面的JS,借助content-scripts可以操作DOM的能力,往页面中插入JS文件,给页面提供调用插件API的能力,以及和background通信的能力。

在插入之前,需配置一下web可访问的资源,同时content-scripts的调用时机换成"document_end"或者"document_idle",不然会无法获取DOM,导致插入失败。在manifest.json中添加以下内容:

{

“content_scripts”: [

{

“matches”: [“<all_urls>”],

“js”: [“./js/content.js”],

“run_at”: “document_end”

},

],

“web_accessible_resources”: [“js/inject.js”],

}

inject.js的内容如下:

function mockApi () {

console.log(‘this is from inject.js’)

}

content.js增加以下代码:

(function () {

let path = ‘js/inject.js’;

let script = document.createElement(‘script’);

script.setAttribute(‘type’, ‘text/javascript’);

// 注意,路径需用Chrome API 生成,这个方法可以获得插件的资源的真实路径。

// 类似:chrome-extension://ihcokhadfjfchaeagdoclpnjdiokfakg/js/inject.js

script.src = chrome.extension.getURL(path);

script.onload = function () {

// 在执行完代码之后移除script标签

this.parentNode.removeChild(this);

}

document.body.appendChild(script);

})();

更新插件后,页面就可以访问inject.js的方法:

permissions

插件后台有的操作需要配置相应的权限,例如本地存储、网络请求、通知等等,示例:

{

“permissions”: [

“contextMenus”, // 右键菜单

“tabs”, // 标签

“notifications”, // 通知

“webRequest”, // web请求

“webRequestBlocking”,

“storage” // 插件本地存储

],

}

完整的manifest配置

官方文档:https://developer.chrome.com/extensions/manifest

通信

popup和background通信

popup可以通过 chrome.extension.getBackgroundPage() API 直接获取到background的上下文,从而调用background的方法来通信:

// popup.js

var backend = chrome.extension.getBackgroundPage();

backend.test(); // 访问bbackground的函数

background可以通过chrome.extension.getViews({type:‘popup’}) 获取到popup的上下文,前提是popup页面是打开的状态下。

let views = chrome.extension.getViews({type:‘popup’});

let popup = null

if(views.length > 0) {

popup = views[0];

// 直接访问popup的函数

popup.test();

}

这里需要注意一点:

在popup页面,你如果想编写js,请将js编写在一个文件里面,然后引入进来,不然会报错,这是因为Chrome的安全政策规定的:https://developer.chrome.com/extensions/contentSecurityPolicy

popup错误示范:

hello world!!

正确姿势:

hello world!!

content-scripts和background通信

content-scripts可以通过 chrome.runtime.sendMessage(message) 给background发送消息:

chrome.runtime.sendMessage(‘message content’, (res) => {

console.log(‘from background:’, res)

});

background通过chrome.runtime.onMessage.addListener()监听content-scripts发送的消息:

chrome.runtime.onMessage.addListener(function(message, sender, callback) {

console.log(mesasge); // meesage content

callback && callback(‘yes this from background’)

});

最后

编程基础的初级开发者,计算机科学专业的学生,以及平时没怎么利用过数据结构与算法的开发人员希望复习这些概念为下次技术面试做准备。或者想学习一些计算机科学的基本概念,以优化代码,提高编程技能。这份笔记都是可以作为参考的。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

名不虚传!字节技术官甩出的"保姆级"数据结构与算法笔记太香了

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值