Расширение Chrome/Firefox - сценарий содержимого не прослушивает сообщения

Я разрабатываю расширение для Chrome и Firefox и столкнулся с проблемой.

По сути, я пытаюсь получить сценарий содержимого для прослушивания сообщений с использованием chrome.runtime.onMessage.addListener(...), однако, похоже, это не работает.

Я проверил это, отправив сообщение из скрипта содержимого. У фонового сценария (ml.js) был прослушиватель, который работал нормально, но lsitener в сценарии содержимого просто не получил сообщение.

Вы можете просмотреть код в этом Gist (или ниже).

manifest.json:

{
    "manifest_version": 2,
    "name": "Messaging Extension",
    "version": "1.0.0",
    "background": {
        "scripts": ["ml.js"]
    },
    "content_scripts": [
        {
            "matches": ["*://*.google.co.uk/*"],
            "js": ["cs.js"],
            "run_at": "document_end"
        }
    ]
}

ml.js:

// When receive message...
chrome.runtime.onMessage.addListener(function(message) {
    if (message.key) {
        console.log('ML: First message received')
        // Send another message
        chrome.runtime.sendMessage({
            'foo': 'bar'
        })
    }
})

cs.js:

// Send message to ml.js
chrome.runtime.sendMessage({
    'key': 'value'
})
chrome.runtime.onMessage.addListener(function(message) {
    console.log('CS: Second message received')
})

При тестировании в Firefox (загрузив надстройку в about:debugging и затем посетив Google) cs.js отправил сообщение и ml.js записал сообщение в консоль, однако cs.js не записал сообщение.

Буду признателен за помощь, спасибо!


person Kaspar Lee    schedule 30.10.2016    source источник
comment
Ожидаете ли вы, что сценарий контента получит отправленное им сообщение? Этого не происходит. Сообщение, отправленное сценарием, не получено этим же сценарием.   -  person Makyen♦    schedule 30.10.2016


Ответы (1)


Использование runtime.sendMessage() (сообщения в фоновые сценарии):

runtime.sendMessage() (Chrome/Firefox) используется для отправки сообщений сценариям, которые выполняются в фоновом контексте (фоновые сценарии, всплывающие окна и т. д.). Даже когда он используется для отправки сообщений из скрипта, который находится в фоновом контексте (например, для общения между всплывающим скриптом и фоновым скриптом), он будет получен другими сценариями фонового контекста, которые в данный момент слушают, но не сценарием, который его отправляет.

Процитируем документацию Google Chrome runtime.sendMessage() (выделено мной):

При отправке на ваш добавочный номер событие runtime.onMessage будет запускаться в каждом фрейме вашего добавочного номера (кроме фрейма отправителя)...

Отправка сообщения вашему скрипту контента (tabs.sendMessage())

Если вы хотите отправить сообщение из фонового сценария в сценарий содержимого, вам следует использовать tabs.sendMessage() (Chrome/Firefox) . В качестве альтернативы вы можете использовать методы connect() в runtime и tabs, которые затем предоставят вам порт (Chrome/Firefox).

Использованная литература:

person Makyen♦    schedule 30.10.2016
comment
Отправка сообщения из скрипта контента была только для демонстрации, но теперь я вижу, что это было неясно (также я не знал, что вы не можете получить сообщение, которое вы отправляете из того же скрипта). Я обновил вопрос (и Gist) новым кодом, демонстрирующим ту же ошибку. Спасибо за помощь! - person Kaspar Lee; 30.10.2016
comment
По сути, даже если сообщение отправлено из ml.js с использованием runtime.sendMessage, сценарий контента не получит его с помощью runtime.onMessage. - person Kaspar Lee; 30.10.2016
comment
@Druzion, это ожидаемое поведение. runtime.sendMessage() предназначен для отправки сообщений скриптам в контексте фонового скрипта (например, фоновые скрипты, всплывающие скрипты и т. д.), а не скриптам контента. Если вы хотите отправить сообщение в свой контент-скрипт, вы должны использовать tabs.sendMessage(). Пожалуйста, ознакомьтесь с документацией, указанной в ссылках выше. - person Makyen♦; 30.10.2016
comment
@Druzion, без проблем. Я рад, что смог помочь. Перечитывая документацию Firefox runtime.sendMessage(), я вижу, что она могла бы быть более ясной. Я добавил его в свой список страниц, которые я должен обновить. - person Makyen♦; 30.10.2016
comment
Да, я читал runtime.sendMessage как способ отправки сообщений в скрипты содержимого, а не из них. - person Kaspar Lee; 30.10.2016