Передача сообщения из background.js в popup.js
Я пытаюсь реализовать свое собственное расширение Chrome, в котором при определенном событии создается уведомление браузера и заполняется всплывающее окно данными, рассчитанными в background.js.
Вот файл mymanifest:
{
"name": "Dummy name",
"description": "Description",
"manifest_version": 2,
"version": "1.1.3",
"icons": {
"16": "icon_16.png",
"48": "icon_48.png",
"128": "icon_128.png",
"256": "icon_256.png"
},
"browser_action": {
"default_icon": "icon_48.png",
"default_title": "Test",
"default_popup": "popup.html"
},
"permissions": ["background","webRequest","webRequestBlocking","webNavigation","tabs","notifications"],
"background": {
"scripts":["jquery-1.8.1.min.js","classy.js","background.js"]
}
}
Мой вызов sendMessage в background.js
show : function(result) {
var that = this;
chrome.extension.sendMessage({greeting: "hello"}, function(response) {
console.log(response);
});
if(window.webkitNotifications) {
var notification = webkitNotifications.createHTMLNotification('notification.html');
notification.show();
setTimeout(function(){
notification.cancel();
}, '7000');
}
}
Слушатель моего сообщения в popup.js (из примеров расширений chrome)
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
Единственная ошибка, которую я получаю, это
Ошибка порта: не удалось установить соединение. Получающий конец не существует.
Спасибо за помощь!
5 ответов
Во всплывающем окне нет идентификатора вкладки, поэтому вы получите сообщение об ошибке.
Ты можешь использовать chrome.runtime.sendMessage
а также chrome.runtime.onMessage.addListener
в таком случае.
Так что в background.js
chrome.runtime.sendMessage({
msg: "something_completed",
data: {
subject: "Loading",
content: "Just completed!"
}
});
И в popup.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.msg === "something_completed") {
// To do something
console.log(request.data.subject)
console.log(request.data.content)
}
}
);
Я надеюсь, что это будет полезно для вас.
Спасибо,
Чтобы решить эту проблему, вы должны сначала отправить сообщение рукопожатия в background.js, а затем отправить фактические данные из background.js в popup.js. Например: в моем случае, что я сделал, было
popup.js
chrome.runtime.sendMessage({data:"Handshake"},function(response){
});
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
str = JSON.stringify(message.data);
});
background.js
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
//alert(message.data);
chrome.runtime.sendMessage({data:datax},function(response){
});
});
Что я пытаюсь сделать, так это то, что как только мы нажимаем на иконку, сообщение рукопожатия отправляется на background.js, и когда оно получает его, мы можем затем отправить переменную или любые данные, которые мы хотели отправить, на popup.js для его рендеринга. на popup.html.
Я нашел два простейших способа отправки данных из background.js в popup.js:
1) Использование хранилища
Сохраните значения в хранилище, и как только всплывающее окно открывается, оно получает значения из хранилища и отображает их во всплывающем окне.
background.js
chrome.storage.sync.set({ 'dataValue1': 'Some data 1.' });
chrome.storage.sync.set({ 'dataValue2': 'Some data 2.' });
popup.js
function updatePopup() {
chrome.storage.sync.get(['dataValue1', 'dataValue2'], function (data) {
document.getElementById("popupElement1").innerText = data.dataValue1;
document.getElementById("popupElement2").innerText = data.dataValue2;
});
}
document.addEventListener('DOMContentLoaded', updatePopup);
popup.html
<html>
<head>
<script src="popup.js"></script>
</head>
<body>
<p id="popupElement1"></p>
<p id="popupElement2"></p>
</body>
</html>
manifest.json
{
"name": "Background2popup",
"version": "1.0",
"manifest_version": 2,
"description": "This is a demo",
"browser_action": {
"default_popup": "popup.html"
},
"background": {
"scripts": [
"background.js"
]
},
"permissions": [
"<all_urls>",
"storage",
"tabs"
]
}
2) Использование chrome.runtime.sendMessage()
После открытия всплывающего окна вы отправляете сообщение из всплывающего окна в фоновый режим, чтобы установить соединение / рукопожатие (в противном случае вы получите сообщение "Unchecked runtime.lastError: Could not install connection. Receiving end is not exists." Если вы попытаетесь отправить сообщение из фона во всплывающее окно, а всплывающее окно не открывается). После установления соединения вы используете sendResponse из фона для отправки данных, которые вы хотите отправить, во всплывающее окно.
background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.method == "getStatus") {
console.log(request.data)
sendResponse({ method: "peepee", data: "poopoo" })
}
});
popup.js
chrome.runtime.sendMessage({ method: "getStatus", data: "fag" }, function (res) {
document.getElementById("popupElement1").innerText = res.method;
document.getElementById("popupElement2").innerText = res.data;
return true;
});
popup.html и manifest.json такие же, как в первом примере
решение localStorage
Поскольку всплывающее окно не имеет постоянного состояния, вы можете использовать localStorage для сохранения состояния всплывающего окна и предварительной загрузки его при открытии всплывающего окна и
storage
событие, чтобы отслеживать изменения состояния, пока всплывающее окно открыто.
Задний план:
localStorage.setItem('popupData', JSON.stringify({ tabReady: true }));
Неожиданно возникнуть:
// Load the state from localStorage when popup opens
let popupData = JSON.parse(localStorage.getItem('popupData'));
// Keep track of changes to the popup state while the popup is open
window.addEventListener('storage', (e) => {
if (e.key === 'popupData') {
popupData = JSON.parse(e.newValue);
console.log(popupData.tabReady);
}
});
Использование runtime.sendMessage
отправлять сообщения в фоновый скрипт, и tabs.sendMessage
от фона к содержанию скрипта.
Обратите внимание, что вам нужно указать идентификатор вкладки:
chrome.tabs.query({ active: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, { greeting: 'hello' }, (response) => {
console.log(response);
});
});
Вы можете найти полный пример и документацию здесь: https://developer.chrome.com/extensions/messaging