在 Chrome 扩展中,扩展脚本之间的信息传递是通过 Chrome 的消息传递系统实现的。消息可以在以下不同的脚本之间传递:
- 内容脚本 (content scripts) 和 后台脚本 (background scripts) 或 扩展页面 (popup, options pages)。
- 后台脚本 (background scripts) 和 扩展页面。
Chrome 提供了两种主要的消息传递机制:
- 短期消息 (one-time requests):一次性发送并接收消息。
- 长连接消息 (long-lived connections):建立持续的通信连接。
- 短期消息传递 (One-time requests)
短期消息传递适用于简单的请求-响应式通信。一个脚本发送消息,另一个脚本接收消息并发送响应。通常用于单次操作,例如请求一些数据或让另一个脚本执行一个操作。
内容脚本与后台脚本之间的短期消息传递
-
从内容脚本发送消息到后台脚本:
// content.js (内容脚本)
// 发送消息到后台脚本
chrome.runtime.sendMessage({ action: ‘greet’, message: ‘Hello from content script’ }, function(response) {
console.log(‘收到后台脚本的响应:’, response);
}); -
在后台脚本中接收并处理消息:
// background.js (后台脚本)
// 监听来自内容脚本或扩展页面的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === ‘greet’) {
console.log(‘收到内容脚本的消息:’, message.message);
sendResponse({ response: ‘Hello from background script’ });
}
}); -
从后台脚本发送消息到内容脚本:
// background.js (后台脚本)
// 获取所有活动的标签页,然后发送消息到指定标签页的内容脚本
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, { action: ‘greet’, message: ‘Hello from background script’ }, function(response) {
console.log(‘收到内容脚本的响应:’, response);
});
}); -
在内容脚本中接收消息:
// content.js (内容脚本)
// 监听来自后台脚本的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === ‘greet’) {
console.log(‘收到后台脚本的消息:’, message.message);
sendResponse({ response: ‘Hello from content script’ });
}
});
扩展页面 (Popup) 与后台脚本之间的短期消息传递
-
从扩展页面发送消息到后台脚本:
// popup.js (扩展页面)
// 发送消息到后台脚本
chrome.runtime.sendMessage({ action: ‘getData’, message: ‘Hello from popup’ }, function(response) {
console.log(‘收到后台脚本的响应:’, response);
}); -
在后台脚本中接收并处理消息:
// background.js (后台脚本)
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === ‘getData’) {
console.log(‘收到扩展页面的消息:’, message.message);
sendResponse({ response: ‘Data from background script’ });
}
});
- 长连接消息传递 (Long-lived connections)
长连接消息适用于需要持续通信的情况。通过 chrome.runtime.connect() 方法建立一个持久的连接,消息可以在连接两端持续传递。
内容脚本与后台脚本之间的长连接消息传递
-
从内容脚本建立连接并发送消息:
// content.js (内容脚本)
// 与后台脚本建立连接
const port = chrome.runtime.connect({ name: ‘content-background’ });// 发送消息
port.postMessage({ action: ‘start’, message: ‘Starting connection from content script’ });// 监听后台脚本的响应
port.onMessage.addListener((message) => {
console.log(‘收到后台脚本的消息:’, message);
}); -
在后台脚本中接收连接并处理消息:
// background.js (后台脚本)
// 监听连接请求
chrome.runtime.onConnect.addListener(function(port) {
console.log(‘收到连接请求:’, port.name);// 监听消息 port.onMessage.addListener(function(message) { if (message.action === 'start') { console.log('内容脚本消息:', message.message); // 发送响应消息 port.postMessage({ response: 'Connection established with background script' }); } });
});
扩展页面与后台脚本之间的长连接消息传递
-
从扩展页面建立连接并发送消息:
// popup.js (扩展页面)
// 与后台脚本建立连接
const port = chrome.runtime.connect({ name: ‘popup-background’ });// 发送消息
port.postMessage({ action: ‘init’, message: ‘Initializing connection from popup’ });// 监听后台脚本的响应
port.onMessage.addListener((message) => {
console.log(‘收到后台脚本的消息:’, message);
}); -
在后台脚本中接收连接并处理消息:
// background.js (后台脚本)
chrome.runtime.onConnect.addListener(function(port) {
console.log(‘收到连接请求:’, port.name);// 监听消息 port.onMessage.addListener(function(message) { if (message.action === 'init') { console.log('扩展页面消息:', message.message); // 发送响应消息 port.postMessage({ response: 'Connection established with background script' }); } });
});
- Manifest 配置
为了启用消息传递,你需要在 manifest.json 中正确配置相关的权限。特别是内容脚本与扩展页面、后台脚本之间通信时,需要确保在 manifest.json 中配置好内容脚本的匹配规则。
{
"manifest_version": 3,
"name": "Message Passing Example",
"version": "1.0",
"permissions": [
"tabs", "activeTab"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}