在上一篇中,我提出了总任务。接下来去实现。
获取网页内容等其它信息,这是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的通讯,我以一张图概括之: