Chrome瀏覽器擴展開發系列之十三:消息傳遞Message

因爲content scripts運行在Web頁面的上下文中,屬於Web頁面的組成部分,而不是Google Chrome擴展程序。可是content scripts又每每須要與Google Chrome擴展程序的其餘部分通訊以共享數據。web

這能夠經過消息傳遞實現,經過彼此互相的消息的監聽與反饋進行通訊。一個消息能夠包含任何有效的JSON對象,如null,boolean,number,string,array,object。chrome

1)      一次性請求與響應模式json

對於一次性請求與響應模式chrome.runtime.sendMessage(obj, function(response){})是從content scripts發生請求消息給Google Chrome擴展程序頁面。post

從Google Chrome擴展程序頁面發送請求消息給content scripts的時候,須要給出當前tab的ID。this

 1 chrome.tabs.query(
 2     {active: true, currentWindow: true}, 
 3     function(tabs) {
 4           chrome.tabs.sendMessage(
 5             tabs[0].id, 
 6             {greeting: "hello"}, 
 7             function(response) {
 8                     console.log(response.farewell);
 9         });
10 });

 

監聽消息時,須要註冊要監聽的消息。url

1 chrome.runtime.onMessage.addListener(
2   function(request, sender, sendResponse) {
3     console.log(sender.tab ?
4                 "from a content script:" + sender.tab.url :
5                 "from the extension");
6     if (request.greeting == "hello")//判斷是否爲要處理的消息
7       sendResponse({farewell: "goodbye"});
8 });

注意:若是爲同一個消息註冊了多個監聽器,則只有第一個監聽器可以調用sendResponse()方法,其餘的監聽器將被忽略。spa

 

2)      保持長期鏈接的模式code

對於保持長期鏈接的模式,在content scripts與Chrome擴展程序頁面之間創建通道(能夠爲通道命名),能夠處理多個消息。在通道的兩端分別擁有一個chrome.runtime.Port對象,用以收發消息。對象

在content scripts主動創建通道以下:blog

1 var port = chrome.runtime.connect({name: "yisheng"});//通道名稱
2 port.postMessage({joke: "Knock knock"});//發送消息
3 port.onMessage.addListener(function(msg) {//監聽消息
4   if (msg.question == "Who's there?")
5     port.postMessage({answer: "yisheng"});
6   else if (msg.question == "Madame who?")
7     port.postMessage({answer: "Madame... Bovary"});
8 });

 

在Google Chrome擴展程序頁面主動創建通道以下:

1 chrome.tabs.query(
2     {active: true, currentWindow: true}, 
3     function(tabs) {
4           var port = chrome.tabs.connect(//創建通道
5             tabs[0].id, 
6             {name: "yisheng"}//通道名稱
7         );
8 });

 

在content scripts或Google Chrome擴展程序頁面,監聽創建鏈接的請求以下:

 1 chrome.runtime.onConnect.addListener(function(port) {
 2   console.assert(port.name == "yisheng");
 3   port.onMessage.addListener(function(msg) {
 4     if (msg.joke == "Knock knock")
 5       port.postMessage({question: "Who's there?"});
 6     else if (msg.answer == "Madame")
 7       port.postMessage({question: "Madame who?"});
 8     else if (msg.answer == "Madame... Bovary")
 9       port.postMessage({question: "I don't get it."});
10   });
11 });

在content scripts或Google Chrome擴展程序頁面的任一端,調用chrome.runtime.Port.disconnect()則關閉鏈接,同時出發disconnect事件。這時,只有另外一端監聽chrome.runtime.Port.onDisconnect事件,則能夠知道鏈接關閉。

 

3)      Google Chrome擴展程序之間消息模式

還能夠在不一樣的Google Chrome擴展程序之間發送消息,只要知道Google Chrome擴展程序的ID。這使得Google Chrome擴展程序能夠發佈服務爲其餘擴展程序所用。

這種Google Chrome擴展程序之間的消息也分爲一次性請求與響應模式保持長期鏈接的模式

Google Chrome擴展程序監聽調用其服務的消息以下:

 1 //一次性請求與響應模式:
 2 chrome.runtime.onMessageExternal.addListener(
 3   function(request, sender, sendResponse) {
 4     if (sender.id == blacklistedExtension)//黑名單
 5       return;  // don't allow this extension access
 6     else if (request.getTargetData)
 7       sendResponse({targetData: targetData});
 8     else if (request.activateLasers) {
 9       var success = activateLasers();
10       sendResponse({activateLasers: success});
11     }
12   });
13 
14 //保持長期鏈接的模式:
15 chrome.runtime.onConnectExternal.addListener(function(port) {
16   port.onMessage.addListener(function(msg) {
17     // See other examples for sample onMessage handlers.
18   });
19 });

 

發送調用服務的消息以下:

 1 // The ID of the extension we want to talk to.
 2 var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
 3 
 4 // Make a simple request:
 5 chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},
 6   function(response) {
 7     if (targetInRange(response.targetData))
 8       chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});
 9   });
10 
11 // Start a long-running conversation:
12 var port = chrome.runtime.connect(laserExtensionId);
13 port.postMessage(...);

 

4)      Google Chrome擴展程序接收指定的Web頁面發送的消息

Google Chrome擴展程序能夠與一些指定地點Web頁面直接收發消息。

首先,在Google Chrome擴展程序的manifest.json文件設置能夠通訊的Web頁面範圍:

1 "externally_connectable": {
2   "matches": ["*://*.example.com/*"]
3 }

 

其次,在Google Chrome擴展程序中監聽Web頁面的消息以下:

1 chrome.runtime.onMessageExternal.addListener(
2   function(request, sender, sendResponse) {
3     if (sender.url == blacklistedWebsite)
4       return;  // don't allow this web page access
5     if (request.openUrlInEditor)
6       openUrl(request.openUrlInEditor);
7 });

 

最後,在指定的Web頁面中,發送消息以下:

1 // The ID of the extension we want to talk to.
2 var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
3 
4 // Make a simple request:
5 chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
6   function(response) {
7     if (!response.success)
8       handleError(url);
9 });
相關文章
相關標籤/搜索