Передача сообщения из 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

Другие вопросы по тегам