【Chrome插件】零基礎學習Chrome

1.“重新加載”插件問題

在“重新加載”插件時,錯誤的插件將不會加載進去,且不會不錯,只會保留上一次的可用插件,並把啓用去除

2.上下文環境問題

在extension的編寫過程中,會發現:比如我在background.js裏面定義了一個函數,然後在popup頁面中不能調用!進一步研究,你會發現後臺和popup兩者之間,並不能共享變量。事實上,這裏有三個環境(上下文),爲了描述方便,我喜歡稱之爲background、popup、content。算上瀏覽頁面自身的腳本,一共有四個環境。他們相互獨立,擁有不同的上下文,不能共享任何js變量

3.js代碼出錯

在html中直接嵌入的js代碼,錯誤語句之前的代碼都能執行

4.content_script調用頁面js函數

兩種方法可間接執行目標函數
創建一按鈕節點,使其點擊事件自動執行,執行方法爲登陸按鈕執行的方法(起到模擬執行作用)

var body = document.body; 
var input = document.createElement("input"); 
input.type = "button";
body.appendChild(input);
input.setAttribute("onClick","DoSubmit()");//input.onclick=DoSubmit;此種寫法,無法生效
input.click();
同理。給boay增加點擊事件,然後執行
var tmp=document.body.onclick; //保存原來的事件句柄
document.body.setAttribute("onclick","DoSubmit()");
document.body.click();
if(tmp) document.body.onclick=tmp; //恢復原來的事件句柄

5.跨域異步請求案例(如訪問獲得ip接口)

manifest.json
"permissions": [ "http://sneezryworks.sinaapp.com/ip.php" ]
... .js
function httpRequest(url, callback){ 
var xhr = new XMLHttpRequest(); 
xhr.open("GET", url, true); 
xhr.onreadystatechange = function() { 
if (xhr.readyState == 4) { 
callback(xhr.responseText); 
} 
} 
xhr.send(); 
} 
httpRequest('http://sneezryworks.sinaapp.com/ip.php', 		function(ip){ document.getElementById('ip_div').innerText = ip; });

6.background常駐後臺

在Manifest中指定background域可以使擴展常駐後臺。background可以包含三種屬性,分別是scripts、page和persistent
persistent屬性定義了常駐後臺的方式——當其值爲true時,表示擴展將一直在後臺運行,無論其是否正在工作;當其值爲false時,表示擴展在後臺按需運行,這就是Chrome後來提出的Event
Page。Event
Page可以有效減小擴展對內存的消耗,如非必要,請將persistent設置爲false。persistent的默認值爲true。

7.數據存儲

(http://www.ituring.com.cn/book/miniarticle/60274)

  1. 第一種是使用HTML5的localStorage;
  2. 第二種是使用Chrome提供的存儲API;
  3. 第三種是使用Web SQL Database。

(1.)localStorage是HTML5新增的方法
它允許JavaScript在用戶計算機硬盤上永久儲存數據(除非用戶主動刪除)。
localStorage只能儲存字符串型的數據,無法保存數組和對象,但可以通過join、toString和JSON.stringify等方法先轉換成字符串再儲存
通過聲明unlimitedStorage權限,Chrome擴展和應用可以突破這一限制
ex:
var city = localStorage.city || ‘beijing’;//讀取city值,沒有則默認爲’beijing’
localStorage.city = document.getElementById(‘city’).value;
localStorage除了使用localStorage.namespace的方法引用和寫入數據外,還可以使用localStorage[‘namespace’]的形式。請注意第二種方法namespace要用引號包圍,單引號和雙引號都可以。如果想徹底刪除一個數據,可以使用localStorage.removeItem(‘namespace’)方法。

首先localStorage是基於域名的,這在前面的小節中已經提到過了。而content_scripts是注入到用戶當前瀏覽頁面中的,如果content_scripts直接讀取localStorage,所讀取到的數據是用戶當前瀏覽頁面所在域中的。所以通常的解決辦法是content_scripts通過runtime.sendMessage和background通信,由background讀寫擴展所在域(通常是chrome-extension://extension-id/)的localStorage,然後再傳遞給content_scripts。
(2.)chromeAPI
對於每種儲存區域,Chrome又提供了5個方法,分別是get、getBytesInUse、set、remove和clear。

8.擴展頁面間的通信

(http://www.ituring.com.cn/book/miniarticle/60272)
Chrome提供了4個有關擴展頁面間相互通信的接口,分別是runtime.sendMessage、runtime.onMessage、runtime.connect和runtime.onConnect
runtime.sendMessage完整的方法爲:
chrome.runtime.sendMessage(extensionId, message, options, callback)
runtime.onMessage完整的方法爲:
chrome.runtime.onMessage.addListener(callback)

爲了進一步說明,下面舉一個例子。
在popup.html中執行如下代碼:
chrome.runtime.sendMessage(‘Hello’, function(response){ document.write(response); });
在background中執行如下代碼:
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ if(message == ‘Hello’){ sendResponse(‘Hello from background.’); } });

9.不要在popup頁面的js空間變量中保存數據。

由於popup頁面只在用戶點擊圖標時纔會開啓,當用戶關閉這個頁面時就會停止,並沒有一個從始至終的實例分配給popup頁面。所以每當用戶打開popup頁面時,它都是嶄新的,之前保存在變量中的數據都會消失。如果需要通過popup頁面保存用戶的數據,可以通過通信將數據交給後臺頁面處理,或者通過localStorage和chrome.storage將數據保存在用戶的硬盤上。

10.右鍵菜單

Chrome提供了三種方法操作右鍵菜單,分別是create、update和remove,對應於創建、更新和移除操作。

chrome.contextMenus.create({ type: 'normal', title: 'Menu A', id: 'a' });
chrome.contextMenus.create({ type: 'radio', title: 'Menu B', id: 'b', checked: true }); 
chrome.contextMenus.create({ type: 'checkbox', title: 'Menu D', id: 'd', checked: true });

11.地址欄Omnibox有四種事件:

onInputStarted、onInputChanged、onInputEntered和onInputCancelled,分別用於監聽用戶開始輸入、輸入變化、執行指令和取消輸入行爲。其中執行指令是指用戶敲擊回車鍵或用鼠標點擊建議結果。

12.content_script 匹配規則:

http://open.chrome.360.cn/extension_dev/match_patterns.html)
另外, 這兩個屬性與matches屬性的語法是不同的, 它們更靈活一些。 在這兩個屬性中可以包含號和?號作爲通配符。 其中可以匹配任意長度的字符串,而?匹配任意的單個字符。
例如,語句"http://???.example.com/foo/"" 可以匹配下面的所有情況:
"http://www.example.com/foo/bar"
"http://the.example.com/foo/"
但是它不能匹配下面的這些情況:
"http://my.example.com/foo/bar"
"http://example.com/foo/"
"http://www.example.com/foo
這裏展示一些不合法的模式匹配的例子:
錯誤的模式匹配 錯誤原因
http://www.google.com 沒有說明路徑
http://foo/bar 在域名部分使用’‘時,’
‘後邊只能是’.’ 或者 ‘/’
http://foo..bar/baz 如果’'出現在host部分時, ''只能出現在開頭
http:/bar 少寫了協議分隔符("/" 應該是"//")
foo://
無效的協議

13.Manifest的content_scripts屬性值爲數組類型

數組的每個元素可以包含matches、exclude_matches、css、js、run_at、all_frames、include_globs和exclude_globs等屬性。其中
matches屬性定義了哪些頁面會被注入腳本,
exclude_matches則定義了哪些頁面不會被注入腳本,
css和js對應要注入的樣式表和JavaScript,
run_at定義了何時進行注入,
all_frames定義腳本是否會注入到嵌入式框架中,
include_globs和exclude_globs則是全局URL匹配,最終腳本是否會被注入由matches、exclude_matches、include_globs和exclude_globs的值共同決定。簡單的說,如果URL匹配mathces值的同時也匹配include_globs的值,會被注入;如果URL匹配exclude_matches的值或者匹配exclude_globs的值,則不會被注入

ps:run_at:
控制JS文件注入的時機,如"document_start", “document_end”, “document_idle”。默認"document_idle"
"document_start"表示在CSS文件之後,DOM構建或其他腳本運行之前,注入JS文件。
“document_end”,表示在DOM構建結束之後,圖片或框架加載之前,注入JS文件。
"document_idle"表示在"document_end"與觸發window.onload事件之間的某個時間,注入JS文件,具體時間可以根據頁面的內容和加載的進度優化。

14.網絡通信

Chrome應用通過sockets接口支持TCP和UDP協議,使網絡通信成爲可能。使用sockets接口時,聲明權限比較特殊,並不在permissions中聲明,而是直接在Manifest的sockets中聲明

"sockets": { 
"udp": {
		 "send": ["192.168.1.106:8000", ":8001"], "bind": ":8000" 
	}, "tcp" : { 
		"listen": ["host-pattern1", ...], ...
	 }
 }

如果想連接任意主機的任意端口可以聲明爲"send": “*”。主機和端口可以是一個特定的字符串,也可以是一個數組表示多個規則,如"bind": [":8000", “:8001”]。如果想連接192.168.1.106的任意端口可以聲明爲"send": “192.168.1.106”
a. UDP(http://www.ituring.com.cn/book/miniarticle/74723)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章