无法将消息从上下文菜单发送到内容脚本
Unable to send message from context menu to content script
我想在用户选择上下文菜单项时向内容脚本发送消息。然后,内容脚本将根据消息根据需要格式化网页。
我无法这样做,但我已经能够将问题定位到负责发送消息的代码(在上下文菜单脚本中)或负责接收消息的代码(在内容脚本中)。
下面,我尝试展示一个试图重现问题的代码的简化版本:
manifest.json
{
"manifest_version": 2,
"name": "MCVE for SO",
"version": "1",
"description": "Demonstrate message passing from context menu to content script",
"author": "Nityesh Agarwal",
"permissions": [
"tabs",
"activeTab",
"contextMenus"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["markr.js"]
}
],
"background": {
"scripts": ["backgroundContextMenus.js"]
}
}
backgroundContextMenus.js:
chrome.runtime.onInstalled.addListener(function(){
chrome.contextMenus.create({"title": "Testing",
"contexts": ["selection"],
"id": "testing"});
});
chrome.contextMenus.onClicked.addListener(function(info, tab){
console.log("testing..");
console.log("Before sending the bold message");
chrome.tabs.sendMessage(tab.id, {changeParameter: "bold"});
console.log("After sending the bold message");
});
markr.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse){
console.log("Text toggled bold");
});
选择上下文菜单项后,console
会显示以下消息:
backgroundContextMenus.js:8 testing..
backgroundContextMenus.js:9 Before sending the bold message
backgroundContextMenus.js:11 After sending the bold message
所以,正如您可能注意到的,没有日志说
Text toggled bold
这意味着 markr.js
文件中的代码没有被执行。因此,我怀疑负责发送消息的代码一定有问题:chrome.tabs.sendMessage(tabs[0].id, {changeParameter: "bold"});
)
这是我尝试复制的另一个代码片段,但它给出了同样的问题 -
我无法弄清楚它究竟有什么问题。如果有人可以帮助我告诉我如何在上下文菜单和内容页面之间成功传递消息,那将会很有帮助。
根据 this answer 的提示,我修改了我的 backgroundContextMenus.js 如下:
function ensureSendMessage(tabId, message, callback){
chrome.tabs.sendMessage(tabId, {ping: true}, function(response){
if(response && response.pong) { // Content script ready
chrome.tabs.sendMessage(tabId, message, callback);
} else { // No listener on the other end
console.log("Injecting script programmatically");
chrome.tabs.executeScript(tabId, {file: "markr.js"}, function(){
if(chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
throw Error("Unable to inject script into tab " + tabId);
}
// OK, now it's injected and ready
console.log("Sending msg now");
chrome.tabs.sendMessage(tabId, message, callback);
});
}
});
}
chrome.runtime.onInstalled.addListener(function(){
chrome.contextMenus.create({"title": "Testing",
"contexts": ["selection"],
"id": "testing"});
});
chrome.contextMenus.onClicked.addListener(function(info, tab){
ensureSendMessage(tab.id, {greeting: "hello"});
});
然后我修改了markr.js如下:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
if(request.ping){
sendResponse({pong: true});
return;
}
console.log("Text toggled bold");
});
现在控制台日志正是人们所期望的:
控制台日志:
markr.js:11 Text toggled bold
请记住,此日志是网页开发工具的控制台日志,而不是后台脚本的检查视图。
我想在用户选择上下文菜单项时向内容脚本发送消息。然后,内容脚本将根据消息根据需要格式化网页。
我无法这样做,但我已经能够将问题定位到负责发送消息的代码(在上下文菜单脚本中)或负责接收消息的代码(在内容脚本中)。
下面,我尝试展示一个试图重现问题的代码的简化版本:
manifest.json
{
"manifest_version": 2,
"name": "MCVE for SO",
"version": "1",
"description": "Demonstrate message passing from context menu to content script",
"author": "Nityesh Agarwal",
"permissions": [
"tabs",
"activeTab",
"contextMenus"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["markr.js"]
}
],
"background": {
"scripts": ["backgroundContextMenus.js"]
}
}
backgroundContextMenus.js:
chrome.runtime.onInstalled.addListener(function(){
chrome.contextMenus.create({"title": "Testing",
"contexts": ["selection"],
"id": "testing"});
});
chrome.contextMenus.onClicked.addListener(function(info, tab){
console.log("testing..");
console.log("Before sending the bold message");
chrome.tabs.sendMessage(tab.id, {changeParameter: "bold"});
console.log("After sending the bold message");
});
markr.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse){
console.log("Text toggled bold");
});
选择上下文菜单项后,console
会显示以下消息:
backgroundContextMenus.js:8 testing..
backgroundContextMenus.js:9 Before sending the bold message
backgroundContextMenus.js:11 After sending the bold message
所以,正如您可能注意到的,没有日志说
Text toggled bold
这意味着 markr.js
文件中的代码没有被执行。因此,我怀疑负责发送消息的代码一定有问题:chrome.tabs.sendMessage(tabs[0].id, {changeParameter: "bold"});
)
这是我尝试复制的另一个代码片段,但它给出了同样的问题 -
我无法弄清楚它究竟有什么问题。如果有人可以帮助我告诉我如何在上下文菜单和内容页面之间成功传递消息,那将会很有帮助。
根据 this answer 的提示,我修改了我的 backgroundContextMenus.js 如下:
function ensureSendMessage(tabId, message, callback){
chrome.tabs.sendMessage(tabId, {ping: true}, function(response){
if(response && response.pong) { // Content script ready
chrome.tabs.sendMessage(tabId, message, callback);
} else { // No listener on the other end
console.log("Injecting script programmatically");
chrome.tabs.executeScript(tabId, {file: "markr.js"}, function(){
if(chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
throw Error("Unable to inject script into tab " + tabId);
}
// OK, now it's injected and ready
console.log("Sending msg now");
chrome.tabs.sendMessage(tabId, message, callback);
});
}
});
}
chrome.runtime.onInstalled.addListener(function(){
chrome.contextMenus.create({"title": "Testing",
"contexts": ["selection"],
"id": "testing"});
});
chrome.contextMenus.onClicked.addListener(function(info, tab){
ensureSendMessage(tab.id, {greeting: "hello"});
});
然后我修改了markr.js如下:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
if(request.ping){
sendResponse({pong: true});
return;
}
console.log("Text toggled bold");
});
现在控制台日志正是人们所期望的:
控制台日志:
markr.js:11 Text toggled bold
请记住,此日志是网页开发工具的控制台日志,而不是后台脚本的检查视图。