Chrome
插件各模块之间的音讯传递
一、音讯传递
1. 音讯传递分类
-
Chrome
插件的Action
、Background
和content_script
三个模块之间的信息传输 - 插件和插件之间的信息传输
- 网页向插件进行信息传输
- 与原生运用进行音讯传递
2. 音讯传递 API
-
runtime API
runtime.sendMessage()
runtime.onMessage.addListener()
runtime.connect()
runtime.onConnect.addListener()
runtime.onMessageExternal
runtime.onConnectExternal
- …
-
tabs API
tabs.sendMessage()
tabs.connect()
- …
3. 音讯传递 API
类别
- 一次性请求
sendMessage
- 长时间连接(允许发送多条音讯)
connect
二、chrome
字段展示
1. Action chrome
字段包括内容
-
Action chrome
内容 共 13 个'loadTimes', 'csi', 'action', 'dom', 'extension', 'i18n', 'management', 'permissions', 'runtime', 'scripting', 'storage', 'tabs', 'windows'
-
Chrome.runtime
内容 共 35 个:
'id','onRestartRequired','onUserScriptMessage','onMessageExternal','onMessage','onUserScriptConnect','onConnectExternal','onConnect','onBrowserUpdateAvailable','onUpdateAvailable','onSuspendCanceled','onSuspend','onInstalled','onStartup','connect','getBackgroundPage','getContexts','getManifest','getPackageDirectoryEntry','getPlatformInfo','getURL','openOptionsPage','reload','requestUpdateCheck','restart','restartAfterDelay','sendMessage','setUninstallURL','ContextType','OnInstalledReason','OnRestartRequiredReason','PlatformArch','PlatformNaclArch','PlatformOs','RequestUpdateCheckStatus'
2. Background chrome
字段包括内容
-
Background chrome
内容
共 13 个
'loadTimes', 'csi', 'action', 'dom', 'extension', 'i18n', 'management', 'permissions', 'runtime', 'scripting', 'storage', 'tabs', 'windows'
-
Chrome.runtime
内容 共 34 个
'id', 'onRestartRequired', 'onUserScriptMessage', 'onMessageExternal', 'onMessage', 'onUserScriptConnect', 'onConnectExternal', 'onConnect', 'onBrowserUpdateAvailable', 'onUpdateAvailable', 'onSuspendCanceled', 'onSuspend', 'onInstalled', 'onStartup', 'connect', 'getContexts', 'getManifest', 'getPlatformInfo', 'getURL', 'openOptionsPage', 'reload', 'requestUpdateCheck', 'restart', 'restartAfterDelay', 'sendMessage', 'setUninstallURL', 'ContextType', 'OnInstalledReason', 'OnRestartRequiredReason', 'PlatformArch', 'PlatformNaclArch', 'PlatformOs', 'RequestUpdateCheckStatus', 'getBackgroundClient'
3. Content script chrome
内容
-
Content script chrome
内容
共 7 个
'csi','dom','extension','i18n','loadTimes','runtime','storage'
-
Chrome.runtime
内容
共 14 个
'id', 'onMessage', 'onConnect', 'ContextType', 'OnInstalledReason', 'OnRestartRequiredReason', 'PlatformArch', 'PlatformNaclArch', 'PlatformOs', 'RequestUpdateCheckStatus','connect','getManifest','getURL','sendMessage'
经过上图能够看出不同的模块中的 chrome
字段包括的内容不一样,不同的 runtime
字段包括的内容也不一样,可是都有 sendMessage
能够进行音讯发送
三、音讯传递示例
1. Action(popup)
和 background(service worker)
之间的通讯
1.1. 在 popup
中的 index.js
中增加点击事情,进行音讯发送
-
popup
中运用chrome.runtime.sendMessage
进行音讯发送
plugin_search_but.onclick = function () {
chrome.runtime.sendMessage({
action: 'fromPopup',
message: 'Hello from Popup!'
});
}
1.2. 在 service_worker.js
中接纳音讯
-
service_worker
中运用chrome.runtime.onMessage.addListener
进行音讯监听,经过.action
来判别来历
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
if (message.action === 'fromPopup') {
chrome.notifications.create(
{
type: "basic",
title: "Notifications Title",
message: "Notifications message to display",
iconUrl: "../icons/icon.png"
},
(notificationId) => {
console.log('notificationId-->', notificationId)
}
);
}
});
1.3. 音讯中心音讯弹出
2. Content script
和 background(Service Worker)
通讯
2.1. 在 content_scripts
中增加点击事情进行音讯发送
-
content_scripts
中运用chrome.runtime.sendMessage
进行音讯发送
$('#contentBut').click(async (e) => {
// 发送音讯
chrome.runtime.sendMessage({action: "fromContent"});
})
2.2. 在 Service_worker.js
里边进行音讯接纳
-
service_worker
中运用chrome.runtime.onMessage.addListener
进行音讯监听,经过.action
来判别来历
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
if (message.action === 'fromContent') {
chrome.notifications.create(
{
type: "basic",
title: "Notifications Title",
message: "Notifications message to display",
iconUrl: "../icons/icon.png"
},
(notificationId) => {
console.log('notificationId-->', notificationId)
}
);
}
});
2.3. 音讯中心弹出
3. Action(popup)
和 content
通讯
因为 content
是注入页面的脚本,所以和 content
通讯,需求获取当时 tab
信息
1. 获取当时 tab
信息
// 以豆瓣举例
const [tab] = await chrome.tabs.query({
url: ["https://movie.douban.com/*"],
active: true,
currentWindow: true
});
console.log('tab', tab)
2. popup
向 content
发送音讯,content
接纳音讯
2.1 popup
中运用 chrome.tabs.sendMessage
发送音讯,content
中运用 chrome.runtime.onMessage.addListener
接纳音讯
-
popup
代码
plugin_search_but.onclick = async function () {
const [tab] = await chrome.tabs.query({
url: ["https://movie.douban.com/*"],
active: true,
currentWindow: true
});
console.log('tab', tab)
if (tab) {
// 运用 chrome.tabs.sendMessage 发送音讯
chrome.tabs.sendMessage(tab.id, {
action: 'fromPopup2Content'
})
}
}
-
content
运用chrome.runtime.onMessage.addListener
进行音讯监听
chrome.runtime.onMessage.addListener((e) => {
console.log('e', e)
})
- 控制台输出
2.2 popup
中运用 chrome.tabs.connect
发送音讯,content
运用 chrome.runtime.onConnect.addListener
来接纳音讯
-
popup
代码
plugin_search_but.onclick = async function () {
const [tab] = await chrome.tabs.query({
url: ["https://movie.douban.com/*"],
active: true,
currentWindow: true
});
console.log('tab', tab)
if (tab) {
const connect = chrome.tabs.connect(tab.id, {name: 'fromPopup2Content'});
console.log('connect', connect)
connect.postMessage('这里是弹出框页面,你是谁?')
connect.onMessage.addListener((mess) => {
console.log(mess)
})
}
}
-
content
中运用chrome.runtime.onConnect.addListener
进行音讯监听
chrome.runtime.onConnect.addListener((res) => {
console.log('contentjs中的 chrome.runtime.onConnect:',res)
if (res.name === 'fromPopup2Content') {
res.onMessage.addListener(mess => {
console.log('contentjs中的 res.onMessage.addListener:', mess)
res.postMessage('哈哈哈,我是contentjs')
})
}
})
- 日志输出
content
页面日志输出
popup
页面日志输出
4. 与其他插件进行通讯
4.1. 如需监听传入请求和来自其他插件的连接,需运用 runtime.onMessageExternal
或 runtime.onConnectExternal
方法
// 一次性请求
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === blocklistedExtension)
return; // don't allow this extension access
else if (request.getTargetData)
sendResponse({targetData: targetData});
else if (request.activateLasers) {
var success = activateLasers();
sendResponse({activateLasers: success});
}
});
// 长时间连接
chrome.runtime.onConnectExternal.addListener(function(port) {
port.onMessage.addListener(function(msg) {
// See other examples for sample onMessage handlers.
});
});
4.2. 要向其他插件发送音讯,需求其他插件的 ID
// 插件 ID
var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
// 一次性请求
chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},
function(response) {
if (targetInRange(response.targetData))
chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});
}
);
// 长时间请求
var port = chrome.runtime.connect(laserExtensionId);
port.postMessage(...);
5. 网页给插件发送音讯
插件也能够接纳和呼应来自其他网页的音讯,但无法向网页发送音讯
5.1. 插件配置
- 如需从网页向插件发送音讯,需求在
manifest.json
中运用"externally_connectable"
指定要与哪些网站通讯 - 这会将
Messaging API
公开给指定的网址格式匹配的任何页面 - 网址格式有必要包括至少一个“二级网域”;也就是说,不支撑 *、*.com、*.co.uk 和 *.appspot.com 等主机名格式
- 也能够运用
<all_urls>
拜访所有网域
{
"externally_connectable": {
"matches": ["https://*.douban.com/*"]
}
}
5.2. 网页向插件发送音讯
- 运用
runtime.sendMessage()
或runtime.connect() API
向特定运用或插件发送音讯 - 需求指定插件 ID
5.2.1 Web
页面
- 运用
runtime.sendMessage()
或runtime.connect() API
向特定运用或插件发送音讯
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
function(response) {
if (!response.success)
handleError(url);
});
5.2.2 service-worker.js
页面
- 运用
runtime.onMessageExternal
或runtime.onConnectExternal API
监听网页中的音讯
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.url === blocklistedWebsite) // 当 URL 等于设置的 blocklistedWebsite 时
return;
if (request.openUrlInEditor)
openUrl(request.openUrlInEditor);
});
6. 原生音讯传递
插件能够运用与其他音讯传递
API
类似的API
与原生运用交流音讯,支撑此功能的原生运用有必要注册可与插件进行通讯的原生音讯传递主机。Chrome
会在单独的进程中启动主机,并运用标准输入和标准输出流与其进行通讯
6.1. 原生音讯传递主机配置文件
如需注册原生音讯传递主机,运用有必要保存一个定义原生音讯传递主机配置的文件,示例如下:
{
"name": "com.my_company.my_application",
"description": "My Application",
"path": "C:\Program Files\My Application\chrome_native_messaging_host.exe",
"type": "stdio",
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
}
JSON
文件必需包括以下字段
-
name
:原生音讯传递主机的名称,客户端将此字符串传递给runtime.connectNative()
或runtime.sendNativeMessage()
- 此名称只能包括小写字母数字字符下划线和英文句号
-
description
:运用阐明 -
path
:二进制文件的途径 -
type
:接口类型stdio
stdin
stdout
-
allowed_origins
:插件 ID 列表
6.2. 连接到原生运用
向原生运用收发音讯与跨插件音讯传递非常相似。首要差异在于,运用的是 runtime.connectNative()
而非 runtime.connect()
,运用的是 runtime.sendNativeMessage()
而不是 runtime.sendMessage()
需求在权限中声明 nativeMessaging
权限
service_worker.js
中进行音讯监听和音讯发送
- 运用
connectNative
var port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function (msg) {
console.log('Received' + msg);
});
port.onDisconnect.addListener(function () {
console.log('Disconnected');
});
port.postMessage({text: 'Hello, my_application'});
- 运用
sendNativeMessage
chrome.runtime.sendNativeMessage(
'com.my_company.my_application',
{text: 'Hello'},
function (response) {
console.log('Received ' + response);
}
);