在chrome插件的開發過程中,我遇到了一些問題,在網上找了不少文章,可能是瀏覽器升級的原因,有一些是有效的也有無效的。下面我簡單的分享一下我遇到的坑,以及我把這些坑的解決方案整理而成的js庫 —— crxTool 。
一、坑和鏟子
1、browser action或page action與content script通信
在網上找了不少方法,最后選擇的方法如下:
發送消息:
1 var send= function(data, cb){ 2 chrome.tabs.query({active:true}, function(tab) { 3 chrome.tabs.sendMessage(tab[0].id, { 4 5 data: data 6 }, function(res) { 7 //cb && cb(res); 8 if(cb){ 9 cb(res); 10 } 11 }); 12 }); 13 },
接收消息:
1 var sendListen=function(cb){ 2 chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { 3 4 cb(request.data, sender, sendResponse); 5 6 }); 7 }
如上面的代碼,我們把消息發送給當前頁面 tab[0].id 並處理回調
2、讀取頁面的script標簽包裹的js內容
一般來說,瀏覽器處於安全限制,content script 中只能獲取js文件中的全局變量。但是對於script標簽中的變量,是不能通過content script直接訪問的,可能是防止content script獲取后台模板吐在頁面上的用戶信息。但是查閱文檔,我們可以發現 chrome瀏覽器允許用戶獲取頁面DOM,這就為我們的帶來了新的思路——解析HTML結構。
試想以下通過正則的方式解析字符串化的html,就可以拿到在script標簽中定義的變量,但這個方法有一個缺點,就是我拿到的是初次聲明 定義時的值,如果后面有js改動,則拿不到,但是一般這種變量都是后台吐出來,給前端讀取的燒友改動。所以這種情況下,我們的方法是奏效的。
二、crxTool
crxTool是我根據上面的一些解決方案寫的一個在chrome插件中使用的js庫。github地址—— https://github.com/grARM/crxTool
主要提供了以下API,供大家使用
crxTool.send(tag, data, cb)
用於從chrome擴展中想當前頁面的content script 發送數據,其中tag為自定義的字符串類型,用於表示發送數據的標識,以方便content script在接收數據的時候區分數據的來源。data為要傳遞的數據對象。cb為數據被接收后的回調函數。
crxTool.send("getDomWidth", {"id": 'box-1'}, function (res){
console.log('box-1 元素的寬度為: ', res.width);
});
crxTool.sendListen(tag, cb)
用於在 content script接收數據,其中tag為自定義的字符串類型,用於表示接收數據的標識,crxTool.send的tag對應的時候,即可接收到send發送的數據。cb表示處理接收數據的函數,與chrome.api中chrome.runtime.onMessage.addListener的處理函數保持一致的參數列表,使用方法如下:
crxTool.sendListen('getDomWidth', function (request, sender, sendResponse){
sendResponse({width: document.getElementById(request.id).offsetWidth});
});
crxTool.getPageValue(valueName)
用於在content script 獲取當前頁面中的頁面變量。由於chrome有安全限制,不能直接獲取在頁面中script標簽包裹的頁面變量,比如token和頁面信息,這些變量可能是通過服務端模板渲染好的,輸出在頁面中,以在頁面中定義為全局變量供js文件中去獲取。往往這些變量對我們的chrome 擴展程序很重要,但chrome不允許 content script 直接獲取頁面變量。crxTool提供一個函數用於根據參數 valueName獲取變量定義處的數值作為返回值。
例如頁面中如下定義:
<script type="text/javascript">
var pageObj = {
userName: 'abc',
otherList: ['sasda','dsadasda','sasdad']
}
</script>
crxTool.getPageValue(valueName);
=>{"userName": "abc","otherList": ["sasda","dsadasda","sasdad"]}
