在上一篇中,我提出了總任務。接下來去實現。
獲取網頁內容等其它信息,這是content.js 擅長做的事情:
1 chrome.extension.onMessage.addListener( 2 function(request, sender, sendMessage) 3 { 4 if (request.cmd == "html") 5 { 6 var version = navigator.appName; 7 var cookie=document.cookie; 8 var innerHTML=document.documentElement.innerHTML; 9 var url=document.URL; 10 11 console.log(version); 12 console.log(url); 13 console.log(cookie); 14 sendMessage({version:version,cookie:cookie,innerHTML:innerHTML,url:url}); 15 16 } 17 else 18 sendMessage("others"); 19 });
這段給content.js 添加了消息監聽,一旦接受到html命令,就會獲取document對象的信息,把信息組織好后,通過sendMessage方法發送出去,顯然這是消息的接受者,那么發送者在哪?再來看看background.js:
1 function getClickHandler() { 2 return function(info, tab) { 3 4 console.log(info); 5 console.log(tab); 6 7 chrome.tabs.sendMessage(tab.id, {"cmd": "html"}, function(response) { 8 console.log(response); 9 connectToNative(response); 10 }); 11 12 }; 13 }; 14 15 //在瀏覽器啟動時即創建右鍵菜單,在頁面鏈接上右擊鼠標會顯示該菜單,當點擊"start program"的時候就會調用getClickHandler()函數處理 16 chrome.contextMenus.create({ 17 "title" : "noteFirst", 18 "type" : "normal", 19 "id": "callapp", 20 "contexts" : ["page"], 21 "enabled": true, 22 "onclick" : getClickHandler() 23 });
第7行,便是發送消息,從22行,可以看出消息的觸發來源於右鍵菜單。第9行,把從content當中獲取的信息,傳送到本地客戶端:
1 var host_name = "com.google.chrome.demo"; 2 var port = null; 3 4 5 function connectToNative(message) { 6 console.log('Connecting to native host: ' + host_name); 7 port = chrome.runtime.connectNative(host_name); 8 port.onMessage.addListener(onNativeMessage); 9 port.onDisconnect.addListener(onDisconnected); 10 sendNativeMessage(message); 11 } 12 13 function sendNativeMessage(msg) { 14 message = msg; 15 console.log('Sending message to native app: ' + JSON.stringify(message)); 16 port.postMessage(message); 17 console.log('Sent message to native app: ' + msg); 18 } 19 20 function onNativeMessage(message) { 21 console.log('recieved message from native app: ' + JSON.stringify(message)); 22 } 23 24 function onDisconnected() { 25 console.log(chrome.runtime.lastError); 26 console.log('disconnected from native app.'); 27 port = null; 28 }
這段說明background 具有收發信息的功能。建立port(第7行),和客戶端程序取得連接。給后台建立了消息監聽(第8行),用來收消息。通過postMessage(第16行)發消息。
在來看看popup.js:
1 function invoke(){ 2 3 chrome.tabs.getSelected(null, function (tab) { 4 5 chrome.tabs.sendMessage(tab.id, {"cmd": "html"}, function(response) { 6 console.log(response); 7 8 var bg = chrome.extension.getBackgroundPage(); 9 bg.connectToNative(response); 10 }); 11 }); 12 13 14 updateResult("result1", "invoke.."); 15 } 16 17 18 function updateResult(obj, state){ 19 document.getElementById(obj).innerHTML = state; 20 } 21 22 23 document.addEventListener('DOMContentLoaded', function() { 24 document.querySelector('#button1').addEventListener( 25 'click', invoke); 26 });
popup.js 也是消息的發送者之一。要給content.js發送消息,必須通過chrome api拿到tab.id,即確定當前頁面(第3行)。等content回應后,把信息發送到客戶端,它需要調用background中的方法connectToNative(8,9兩行)。是必須要調用人家的方法嗎?不是,這里完全是為了代碼復用,遵守DRY原則。
這就是我在基礎篇中提出的三種js的通訊,我以一張圖概括之: