Расширение Chrome отправляет сообщение из Background.js в Content Script

Я прочитал документацию о том, как сделать Отправить сообщение из фонового файла javascript (main.js) в Content Script (content.js), но я не могу заставить onMessage открыть свое предупреждение.

Манифест.json

{
   "name": "Example",
   "version": "1.0.1",
   "manifest_version" : 2,
   "description": "Example Description",
   "background" : {
     "scripts" : ["main.js"]
   },
   "page_action" : {
      "default_icon": {
         "19": "icons/19.png",
         "38": "icons/38.png"
      },
      "default_title" : "Example Title"
   },
   "content_scripts": [{
      "matches": ["<all_urls>"],
      "js": ["lib/jquery-1.8.3.min.js","scripts/content.js"],
      "run_at": "document_idle",
      "all_frames": false
   }],
   "permissions": [
       "tabs",
       "geolocation"
   ],
   "icons": {
       "16": "icons/16.png",
       "48": "icons/48.png",
       "128": "icons/48.png"
   }

}

Фоновый файл JavaScript (main.js)

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "SendIt"}, function(response) {});  
});

Файл javascript контента (content.js)

chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
   if (msg.action == 'SendIt') {
      alert("Message recieved!");
   }
});

person Tyler Rafferty    schedule 15.01.2014    source источник
comment
Я думаю, вам нужно вызывать его из вашего popup.js, а не из фона   -  person Pawel Miech    schedule 16.01.2014
comment
Я предполагаю, что фон отправляет сообщение до загрузки сценария содержимого. Не могли бы вы использовать onclick действия вашей страницы, чтобы отправить сообщение?   -  person Teepeemm    schedule 16.01.2014
comment
Предположение Типима очень разумно. Код отображается выше всего, что есть в background.js ? Если нет, что вызывает отправку сообщения на вкладку?   -  person gkalpak    schedule 16.01.2014
comment
Код на фоновой странице выполняется один раз (при запуске Chrome). Когда фоновая страница загружена, нет ни одного документа, содержащего сценарий содержимого. Следовательно, вы не видите никакого предупреждающего сообщения.   -  person Rob W    schedule 16.01.2014
comment
Я поставил плюс RobW и @Teepeeemm за понимание. Я добавил триггер завершения загрузки вкладки перед отправкой сообщения.   -  person Tyler Rafferty    schedule 18.01.2014


Ответы (3)


Благодаря проницательности @Teepeemm я включил завершение загрузки вкладки перед отправкой сообщения в сценарий содержимого.

ДОЖДИТЕСЬ ПОЛНОЙ ЗАГРУЗКИ ВКЛАДКИ

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {          
   if (changeInfo.status == 'complete') {   
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
         chrome.tabs.sendMessage(tabs[0].id, {action: "SendIt"}, function(response) {});  
      });
   }
});
person Tyler Rafferty    schedule 18.01.2014
comment
Будущие программисты, которые обнаружат это, должны знать, что вы не должны использовать действие страницы, чтобы делать что-то на каждой странице, как только она загружается; действие браузера или сценарий содержимого были бы лучше в этом отношении. Но я предполагаю, что в вашем случае у вас есть сверхактивное действие на странице, потому что это то, чем в итоге стал ваш SSCCE. - person Teepeemm; 18.01.2014

Боковое примечание: chrome.extension.onMessage устарело, вы должны использовать chrome.runtime.onMessage - хотя я не верю, что это решит вашу проблему.

Я помню, что у меня была проблема с внедрением мини-файла jquery с использованием скриптов содержимого. Попробуйте использовать неминифицированную версию (например, jquery-1.8.3.js). Сделав это, также добавьте jquery-1.8.3.js в web_accessible_resources в файле манифеста. (Читайте об этом здесь)

Если это все еще не работает, моим последним предложением было бы добавить "<all_urls>" в массив разрешений в вашем манифесте.

person berrberr    schedule 15.01.2014
comment
+1 за предложение правильного chrome.runtime.onMessage. -1 за то, что это не решит проблему (если это будет зависеть от других вещей, но это не главное) -1 за предложение минифицированной версии вызовет проблему (может быть проблема, если исходные карты отсутствуют, но это не так). другая история) -5 за предложение web_accessible_resources, которое не имеет ничего общего с проблемой -10 за предложение <all_urls> ! Совершенно не связанная и большая ошибка с точки зрения безопасности! - person gkalpak; 16.01.2014

Если каждый сценарий объявляет о своем присутствии (я предпочитаю console.log вместо alert), вы видите, что фоновый сценарий запускается один раз (при установке или запуске), а сценарий содержимого запускается с каждой новой страницей. Это означает, что вы захотите, чтобы какое-то внешнее событие инициировало сообщение. Что-то типа

chrome.pageAction.onClicked.addListener(function(tab) {
    chrome.tabs.sendMessage(tab.id,{action:"SendIt"});
});

И не забудьте вызвать chrome.pageAction.show(tabId); по мере необходимости.

person Teepeemm    schedule 17.01.2014