tabs.executeScript() 未在扩展的内容页面中注入脚本
tabs.executeScript() not injecting script in content page of extension
我刚刚开始学习如何在 Firefox 中创建我自己的插件。我正在使用 webExtensions,尽管我发现很难获得全面的文档(我想是因为它仍然是一个新的实现?)。代码似乎一切正常,它在 executeScript 调用后完成了一个 'onExecuted' 函数。但是我注入的脚本 (output.js) 似乎没有触发。在 运行 代码之后,我在 javascript 控制台中收到以下错误:"No matching message handler"。我不确定注入的脚本是否应该是一个独立的 js 文件,或者它是否只是 js 命令的集合。我也尝试了后者(只是一个简单的消息框),但也没有用。
我的代码:
manifest.json:
{
"manifest_version": 2,
"name": "ExportTabs",
"version": "0.9",
"description": "Export/Import Tabs",
"icons": {
"48": "icons/export48.png"
},
"permissions": [
"tabs",
"activeTab",
"<all_urls>"
],
"applications": {
"gecko": {
"id": "938745934875@example.com"
}
},
"browser_action": {
"default_icon": "icons/export.png",
"default_popup": "popup/popup.html"
}
}
我的 popup.html 按下插件按钮时:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>
<button onclick="save()">Save Tabs</button>
<button onclick="view()">View Tabs</button>
</div>
<script src="popup.js"></script>
</body>
</html>
popup.js 文件:
function save() {
chrome.tabs.create({"url": chrome.extension.getURL("popup/output.html")}, onCreated);
}
function onCreated(newTab) {
chrome.tabs.executeScript(newTab.id, {
file: "popup/output.js",
allFrames: true
}, onExecuted);
}
function onExecuted(result) {
alert("inside onExecuted");
}
ouput.html 对于新创建的标签:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>testing stuff</div>
<div id="output"></div>
</body>
</html>
output.js 上面的页面:
//output.js
(function() {
alert("inside output.js");
})();
我应该补充一点,我有 noscript 插件,所以用 "allow scripts globally" 试过了,它仍然给出同样的错误。
为任何帮助干杯。
编辑:我尝试将 executeScript 方法中的 file: "popup/output.js",
替换为 code: 'alert("hello");',
,但仍然无效。
从 OP 发布的答案中移出的信息:
撞。我在另一个带有 ff50.something(beta 通道)的盒子上尝试了这段代码,但注入甚至没有生成 'onExecuted'。但它不会抛出任何错误。基本上弹出窗口有效,之后什么也没有发生。
个别问题分析
问题"No matching message handler"
显示消息 "No matching message handler" 是 49 之前的 Firefox 版本中的一个已知错误。该错误记录为 Bug 1254003。
问题“executeScript
不注入脚本”
在 49+ 版本中,它仍然不起作用,因为这个 documented restriction:
You can only inject code into pages whose URL can be expressed using a
match pattern: meaning, its scheme must be one of "http", "https",
"file", "ftp". This means that you can't inject code into any of the
browser's built-in pages, such as about:debugging, about:addons, or
the page that opens when you open a new empty tab.
因此,您不能使用 tabs.executeScript()
将脚本注入到从您自己的扩展加载的内容中。当我用从 web 加载页面替换从扩展加载页面时,该示例有效:
function save()
{
chrome.tabs.create({"url": "https://en.wikipedia.org/wiki/Bacon"}, onCreated);
}
当您想在从您的扩展加载的页面中执行代码时,通过在您的内容页面中加载脚本文件直接执行 JavaScript
如果您需要将参数传递给加载内容页面内的脚本,您可以在打开选项卡的脚本和打开的选项卡内的脚本之间发送消息。
参见 Content Scripts documentation 的第 "Communicating with background scripts" 章。虽然文档专门针对清单文件中的 "content_scripts",但有关通信的解释也适用于您的情况。
示例代码:
popup.js
中的函数 Save
。
function onCreated(newTab)
{
// Use setTimeOut to give the loaded page some time to register the message listener
setTimeout(onCreatedInner, 500);
function onCreatedInner()
{
console.log("oncreated " + " " + newTab.id);
chrome.runtime.sendMessage(42);
}
}
output.js
:
chrome.runtime.onMessage.addListener(notify);
function notify(message)
{
window.alert(message);
}
问题"JavaScript code in popup is not executed"
在您朋友的设置中,您 运行 遇到了另一个问题:默认情况下,您不允许在 Firefox 的 Web 扩展的内容页面中使用内联脚本。您应该会在浏览器控制台中看到错误
Content Security Policy: The page's settings blocked the loading of a
resource at self
因此,不要对保存按钮使用内联 "onclick",而是从 JavaScript 脚本动态分配 onclick 事件。如何更改 popup.html
:
<button onclick="save" id="buttonSave">Save Tabs</button>
<button >View Tabs</button>
要在 popup.js
开头添加的代码:
var elem = document.getElementById("buttonSave");
elem.onclick = save;
完整的工作示例
这是按预期工作的完整最小示例代码:
文件manifest.json
{
"manifest_version": 2,
"name": "ExportTabs",
"version": "0.9",
"description": "Export/Import Tabs",
"icons": {
"48": "icons/export48.png"
},
"permissions": [
"tabs",
"activeTab",
"<all_urls>"
],
"applications": {
"gecko": {
"id": "938745934875@example.com"
}
},
"browser_action": {
"default_icon": "icons/export.png",
"default_popup": "popup/popup.html"
}
}
文件popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>
<button onclick="save" id="buttonSave">Save Tabs</button>
<button >View Tabs</button>
</div>
<script src="popup.js"></script>
</body>
</html>
文件popup.js
// Register onclick-Event for Save Button
var elem = document.getElementById("buttonSave");
elem.onclick = save;
function save()
{
chrome.tabs.create({"url": chrome.extension.getURL("popup/output.html")}, onCreated);
}
function onCreated(newTab)
{
// Use setTimeOut to give the loaded page some time to register the message listener
setTimeout(onCreatedInner, 500);
function onCreatedInner()
{
chrome.runtime.sendMessage(42);
}
}
文件output.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>testing stuff</div>
<div id="output"></div>
</body>
<script src="output.js"></script>
</html>
文件output.js
// register message handler
chrome.runtime.onMessage.addListener(notify);
function notify(message)
{
// Write message into page
var elem = document.getElementById("output");
elem.innerText = message;
// Show alert
window.alert(message);
}
我刚刚开始学习如何在 Firefox 中创建我自己的插件。我正在使用 webExtensions,尽管我发现很难获得全面的文档(我想是因为它仍然是一个新的实现?)。代码似乎一切正常,它在 executeScript 调用后完成了一个 'onExecuted' 函数。但是我注入的脚本 (output.js) 似乎没有触发。在 运行 代码之后,我在 javascript 控制台中收到以下错误:"No matching message handler"。我不确定注入的脚本是否应该是一个独立的 js 文件,或者它是否只是 js 命令的集合。我也尝试了后者(只是一个简单的消息框),但也没有用。
我的代码: manifest.json:
{
"manifest_version": 2,
"name": "ExportTabs",
"version": "0.9",
"description": "Export/Import Tabs",
"icons": {
"48": "icons/export48.png"
},
"permissions": [
"tabs",
"activeTab",
"<all_urls>"
],
"applications": {
"gecko": {
"id": "938745934875@example.com"
}
},
"browser_action": {
"default_icon": "icons/export.png",
"default_popup": "popup/popup.html"
}
}
我的 popup.html 按下插件按钮时:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>
<button onclick="save()">Save Tabs</button>
<button onclick="view()">View Tabs</button>
</div>
<script src="popup.js"></script>
</body>
</html>
popup.js 文件:
function save() {
chrome.tabs.create({"url": chrome.extension.getURL("popup/output.html")}, onCreated);
}
function onCreated(newTab) {
chrome.tabs.executeScript(newTab.id, {
file: "popup/output.js",
allFrames: true
}, onExecuted);
}
function onExecuted(result) {
alert("inside onExecuted");
}
ouput.html 对于新创建的标签:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>testing stuff</div>
<div id="output"></div>
</body>
</html>
output.js 上面的页面:
//output.js
(function() {
alert("inside output.js");
})();
我应该补充一点,我有 noscript 插件,所以用 "allow scripts globally" 试过了,它仍然给出同样的错误。 为任何帮助干杯。
编辑:我尝试将 executeScript 方法中的 file: "popup/output.js",
替换为 code: 'alert("hello");',
,但仍然无效。
从 OP 发布的答案中移出的信息:
撞。我在另一个带有 ff50.something(beta 通道)的盒子上尝试了这段代码,但注入甚至没有生成 'onExecuted'。但它不会抛出任何错误。基本上弹出窗口有效,之后什么也没有发生。
个别问题分析
问题"No matching message handler"
显示消息 "No matching message handler" 是 49 之前的 Firefox 版本中的一个已知错误。该错误记录为 Bug 1254003。
问题“executeScript
不注入脚本”
在 49+ 版本中,它仍然不起作用,因为这个 documented restriction:
You can only inject code into pages whose URL can be expressed using a match pattern: meaning, its scheme must be one of "http", "https", "file", "ftp". This means that you can't inject code into any of the browser's built-in pages, such as about:debugging, about:addons, or the page that opens when you open a new empty tab.
因此,您不能使用 tabs.executeScript()
将脚本注入到从您自己的扩展加载的内容中。当我用从 web 加载页面替换从扩展加载页面时,该示例有效:
function save()
{
chrome.tabs.create({"url": "https://en.wikipedia.org/wiki/Bacon"}, onCreated);
}
当您想在从您的扩展加载的页面中执行代码时,通过在您的内容页面中加载脚本文件直接执行 JavaScript
如果您需要将参数传递给加载内容页面内的脚本,您可以在打开选项卡的脚本和打开的选项卡内的脚本之间发送消息。
参见 Content Scripts documentation 的第 "Communicating with background scripts" 章。虽然文档专门针对清单文件中的 "content_scripts",但有关通信的解释也适用于您的情况。
示例代码:
popup.js
中的函数 Save
。
function onCreated(newTab)
{
// Use setTimeOut to give the loaded page some time to register the message listener
setTimeout(onCreatedInner, 500);
function onCreatedInner()
{
console.log("oncreated " + " " + newTab.id);
chrome.runtime.sendMessage(42);
}
}
output.js
:
chrome.runtime.onMessage.addListener(notify);
function notify(message)
{
window.alert(message);
}
问题"JavaScript code in popup is not executed"
在您朋友的设置中,您 运行 遇到了另一个问题:默认情况下,您不允许在 Firefox 的 Web 扩展的内容页面中使用内联脚本。您应该会在浏览器控制台中看到错误
Content Security Policy: The page's settings blocked the loading of a resource at self
因此,不要对保存按钮使用内联 "onclick",而是从 JavaScript 脚本动态分配 onclick 事件。如何更改 popup.html
:
<button onclick="save" id="buttonSave">Save Tabs</button>
<button >View Tabs</button>
要在 popup.js
开头添加的代码:
var elem = document.getElementById("buttonSave");
elem.onclick = save;
完整的工作示例
这是按预期工作的完整最小示例代码:
文件manifest.json
{
"manifest_version": 2,
"name": "ExportTabs",
"version": "0.9",
"description": "Export/Import Tabs",
"icons": {
"48": "icons/export48.png"
},
"permissions": [
"tabs",
"activeTab",
"<all_urls>"
],
"applications": {
"gecko": {
"id": "938745934875@example.com"
}
},
"browser_action": {
"default_icon": "icons/export.png",
"default_popup": "popup/popup.html"
}
}
文件popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>
<button onclick="save" id="buttonSave">Save Tabs</button>
<button >View Tabs</button>
</div>
<script src="popup.js"></script>
</body>
</html>
文件popup.js
// Register onclick-Event for Save Button
var elem = document.getElementById("buttonSave");
elem.onclick = save;
function save()
{
chrome.tabs.create({"url": chrome.extension.getURL("popup/output.html")}, onCreated);
}
function onCreated(newTab)
{
// Use setTimeOut to give the loaded page some time to register the message listener
setTimeout(onCreatedInner, 500);
function onCreatedInner()
{
chrome.runtime.sendMessage(42);
}
}
文件output.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>testing stuff</div>
<div id="output"></div>
</body>
<script src="output.js"></script>
</html>
文件output.js
// register message handler
chrome.runtime.onMessage.addListener(notify);
function notify(message)
{
// Write message into page
var elem = document.getElementById("output");
elem.innerText = message;
// Show alert
window.alert(message);
}