如何实现一个谷歌浏览器插件
★Chrome插件就是我们运行在Chrome浏览器 上的扩展程序,比如说vue-devtool。准确的说,其实更应该叫做Chrome扩展,因为插件是更偏向于底层的技术。Chrome插件本质上来说,就是利用WEB开发技术,包括HTML、CSS和JS等开发出来的web页面,用来增强浏览器的功能。它生成的文件结果为一个.crx后缀的压缩包,是Chrome Extension的缩写。 ”
这是插件最重要也是最不可或缺的文件,它包含了插件的所有配置信息。
{
// 必须
"manifest_version": 2, // 清单文件的版本,这个必须写,而且必须是2
"name": "demo", // 插件的名称
"version": "1.0.0", // 插件的版本
// 推荐
"default_locale": "en", // 默认语言
"description": "插件的描述",
"icons": { // 图标,一般偷懒全部用一个尺寸的也没问题
"16": "img/icon.png", // 扩展程序页面上的图标
"32": "img/icon.png", // Windows计算机通常需要此大小。
"48": "img/icon.png", // 显示在扩展程序管理页面上
"128": "img/icon.png" // 在安装和Chrome Webstore中显示
},
// 会一直常驻的后台JS或后台页面
"background":
{
// 2种指定方式,如果指定JS,那么会自动生成一个背景页
"page": "background.html"
"scripts": ["js/background.js"]
},
// 浏览器右上角图标设置
"browser_action":
{
"default_icon": "img/icon.png",
"default_title": "这是一个示例Chrome插件", // 图标悬停时的标题
"default_popup": "popup.html" // 在工具栏点击插件弹出的页面
},
// 当某些特定页面打开才显示的图标,例如vue-devtools
/*"page_action":
{
"default_icon": "img/icon.png",
"default_title": "我是pageAction",
"default_popup": "popup.html"
},*/
// 需要直接注入页面的JS
"content_scripts":
[
{
"matches": ["<all_urls>"], // "<all_urls>" 表示匹配所有地址
// 多个JS按顺序注入
"js": ["js/content-script.js"],
"css": ["css/custom.css"],
"run_at": "document_start"
// document_start: html解析完毕、CSS资源加载完成,JS执行前
// document_end: DOMContentLoaded事件触发后立即执行
// document_idle: 在load之前触发
},
],
// 权限申请
"permissions":
[
"contextMenus", // 右键菜单
"tabs", // 标签
"notifications", // 通知
"webRequest", // web请求
"storage", // 插件本地存储
],
}
"content_scripts":
[
{
"matches": ["<all_urls>"], // "<all_urls>" 表示匹配所有地址
// 多个JS按顺序注入
"js": ["js/jquery-1.8.3.js", "js/content-script.js"],
"css": ["css/custom.css"],
"run_at": "document_start"
},
]
直接将脚本注入到页面中,但是也可以包含CSS文件,但是在注入CSS文件时,要小心,否则会覆盖网页原本的样式。content-scripts中的JS程序和原始页面共享DOM,但是和原始页面的JS不是在同一个环境下运行的,所以我们是无法访问到原始页面中定义的变量的因为是是注入到页面中的,所以在安全策略上不能访问大部分的API,除了下面的四种:
chrome.extension(getURL , inIncognitoContext , lastError , onRequest , sendRequest)
chrome.i18n
chrome.runtime(connect , getManifest , getURL , id , onConnect , onMessage , sendMessage)
chrome.storage
// 会一直常驻的后台JS或后台页面
"background":
{
// 2种指定方式,如果指定JS,那么会自动生成一个背景页
"page": "background.html"
"scripts": ["js/background.js"]
}
// 浏览器右上角图标设置
"browser_action":
{
"default_icon": "img/icon.png",
"default_title": "这是一个示例Chrome插件", // 图标悬停时的标题
"default_popup": "popup.html" // 在工具栏点击插件弹出的页面
},
tips:打开的任何页面都会运行插件程序
// 当某些特定页面打开才显示的图标,例如vue-devtools
"page_action":
{
"default_icon": "img/icon.png",
"default_title": "我是pageAction",
"default_popup": "popup.html"
}
// 在组件安装完成之后注册监听函数
chrome.runtime.onInstalled.addListener(function() {
// 在页面跳转时,移除旧的规则加入新的规则
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// 如果url包含baidu则显示运行
chrome.declarativeContent.onPageChanged.addRules([
{
// That fires when a page's URL contains a 'g' ...
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'baidu' },
})
],
//在匹配成功后执行的操作
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
通过开发Chrome插件可以自定义浏览器的右键菜单,主要是通过chrome.contextMenusAPI实现,右键菜单可以出现在不同的上下文,比如普通页面、选中的文字、图片、链接,等等,如果有同一个插件里面定义了多个菜单,Chrome会自动组合放到以插件名字命名的二级菜单里。
chrome.contextMenus.create({
title: "测试右键菜单",
onclick: function(){alert('您点击了右键菜单!');}
});
JS通信主要体现在下面的几个文件之间
chrome.runtime.sendMessege(
message,
function(response) {…}
)
每个tab页面都有一个自己的content-scripts,而background只有一个,所以往content-scripts发送消息,需要知道是哪一个tab
/**
获取当前选项卡id
@param callback - 获取到id后要执行的回调函数
*/
function getCurrentTabId(callback) {
// 查询所有在当前浏览器打开的活动的tab
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
if (callback) {
callback(tabs.length ? tabs[0].id: null);
}
});
}
这里的callback就可以是我们发送信息的回调函数
chrome.tabs.sendMessage(tabId, message, function(response) {...});
contents-scripts接收
chrome.runtime.onMessege.addListener(
function(request, sender, sendResponse) {…}
)
可以直接获取background实例,然后直接里面定义的方法
var bg = chrome.extension.getBackgroundPage();
bg.someMethod(); //someMethod()是background中的一个方法
本质上与上面的方式相同。