#javascript #firefox-addon #firefox-addon-webextensions
#javascript #firefox-дополнение #firefox-дополнение-webextensions
Вопрос:
Я только начинаю изучать, как создать свой собственный аддон в Firefox. Я использую WebExtensions, хотя мне трудно получить исчерпывающую документацию (я думаю, потому что это все еще новая реализация?). Кажется, что весь код работает нормально, и он завершает функцию ‘onExecuted’ после вызова executeScript. Но мой внедренный скрипт (output.js ), похоже, не срабатывает. После запуска кода я получаю следующую ошибку в консоли javascript: «Нет соответствующего обработчика сообщений». Я не был уверен, должен ли вводимый скрипт быть автономным 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>
The 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, поэтому я попробовал это с помощью «разрешить скрипты глобально», и он по-прежнему выдает ту же ошибку.
Приветствую любую помощь.
редактировать: я попытался заменить file: "popup/output.js",
в методе executeScript на code: 'alert("hello");',
, и это все равно не сработало.
Информация перенесена из ответа, опубликованного OP:
Bump. Я попробовал этот код в другом окне с ff50.something (бета-канал), и внедрение даже не вызывает ‘onExecuted’. Но это не выдает никаких ошибок. В основном всплывающее окно работает, и после этого ничего не происходит.
Ответ №1:
Индивидуальный анализ проблемы
Проблема «Нет соответствующего обработчика сообщений»
То, что отображается сообщение «Нет соответствующего обработчика сообщений», является известной ошибкой в версиях Firefox до 49. Ошибка задокументирована как ошибка 1254003.
Проблема « executeScript
не внедряет скрипт»
В версиях 49 он по-прежнему не работает из-за этого документированного ограничения:
Вы можете вводить код только на страницы, URL-адрес которых может быть выражен с использованием шаблона соответствия: это означает, что его схема должна быть одной из «http», «https», «file», «ftp». Это означает, что вы не можете вводить код ни на одну из встроенных страниц браузера, таких как about: debugging, about: addons или страница, которая открывается при открытии новой пустой вкладки.
Таким образом, вы не можете использовать tabs.executeScript()
для внедрения скриптов в содержимое, загруженное из ваших собственных расширений. Пример работает, когда я заменяю загрузку страницы из расширения загрузкой страницы из Интернета:
function save()
{
chrome.tabs.create({"url": "https://en.wikipedia.org/wiki/Bacon"}, onCreated);
}
Если вы хотите выполнить код на странице, загруженной из вашего расширения, запустите JavaScript напрямую, загрузив файл сценария на страницу содержимого
Если вам нужно передать параметры скрипту внутри страницы загруженного содержимого, вы можете отправлять сообщения между скриптом, который открывает вкладку, и скриптом внутри открытой вкладки.
Смотрите главу «Взаимодействие с фоновыми сценариями» в документации по сценариям содержимого. Хотя документация конкретно посвящена «content_scripts» из файла манифеста, объяснение об обмене данными также применимо к вашей ситуации.
Пример кода:
Функция Save
в popup.js
.
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 во всплывающем окне не выполняется»
При настройке вашего друга вы сталкиваетесь с другой проблемой: по умолчанию вам не разрешено использовать встроенные скрипты на страницах содержимого веб-расширений в Firefox. Вы должны увидеть, что в консоли браузера вы получаете сообщение об ошибке
Политика безопасности содержимого: настройки страницы заблокировали загрузку ресурса при самостоятельной загрузке
Итак, вместо использования встроенного «onclick» с кнопкой сохранить, назначьте событие onclick динамически из вашего скрипта JavaScript. Как изменить 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);
}
Комментарии:
1. Спасибо Девять. Несколько проблем. FF50 даже не создаст новую вкладку, не говоря уже о том, чтобы загрузить в нее что-либо. Я использовал следующее для popup.js :
code
функция save() { chrome.tabs.create({«url»: » en.wikipedia.org/wiki/Bacon «}); } Другая проблема заключается в том, что, насколько я вижу, вы можете обмениваться данными только между content_script и фоновым скриптом, а не скриптом, загруженным через output.html код. Но я не могу загрузить скрипт содержимого, поскольку он принимает только указанные вами шаблоны ограниченного соответствия. Мой output.html является локальным файлом. Есть ли простой способ разместить его где-нибудь для загрузки через http?2. примечание: в приведенном выше примере по какой-то причине добавлена несуществующая точка с запятой. Код: chrome.tabs.create({«url»: » en.wikipedia.org/wiki/Bacon «}); редактировать: я сдаюсь. Он добавил его и сюда. игнорируйте точку с запятой после bacon». Он также сделал гиперссылку на него и удалил h t t p и т.д.
3. @erv Я обновил ответ более подробной информацией. Пожалуйста, будьте более конкретны в отношении возникающих у вас проблем. Всегда проверяйте наличие ошибок или предупреждений в консоли браузера.
4. @erv Если у вас есть более подробная информация по вопросу, обновите вопрос вместо добавления комментариев. Там у вас также есть полная поддержка форматирования исходного кода. В комментариях вы можете использовать обратную метку ` для обозначения исходного кода.
5. Приветствую, Nine, теперь это работает на ff50. Вы были правы насчет ошибки безопасности содержимого. Я пропустил это, поскольку просматривал только ошибки javascript на консоли.