Hi Dai Gei Ho~ 我是Winnie ~
在昨天章節的內容中,我們介紹了如何在 Extension 中使用 Es6 Module,其中 Content Script 因為無相關html頁面來定義使用ES6 Module,所以我們透過 Inject Script Module 的方法來使用 ,增加程式碼的共用性。
但事情總是這樣發展的,有一好可能就有一壞,假使不是必要可以不用使用,就像人生一樣不是什麼都是一定。
為什麼呢?
因為這樣的寫法會產生一些限制,像是無法使用部分 chrome.runtime
的方法,如 chrome.storage
,但...這都沒什麼,最困難是關於 訊息傳遞方法的限制。
什麼意思?假設我們動態注入了這段 Scirpt 在他人網站中:
//background.js
const injectScriptModlue = (url) => {
let script = document.createElement('script');
script.type = "module";
script.src = url;
const head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
head.insertBefore(script, head.lastChild);
}
...略
chrome.scripting.executeScript({
target: {
tabId: tabId // 指定傳入tab 頁
},
func: injectScriptModlue, // 注入func
args: [chrome.runtime.getURL('main.js')] // 傳遞參數
}, () => {});
...略
如下示意圖 此時 main.js
執行範圍此時屬於Extension端,而不是瀏覽器中。
咦?等等。
這樣不是更好,因為main.js
存在於Extension端,可以直接使用runtime.onMessage.addListener
與 runtime.sendMessage
來傳遞就好了,還不用指定tab不是超讚超方便!
wait~wait~wait~ 因為執行環境的原因,還是無法使用。
那這樣 要怎麼與Extension來傳遞訊息呢?
可以,只是要繞道而行
在Extension相關方法中,有提供 externally_connectable
權限 搭配在後台 監聽chrome.runtime.onMessageExternal.addListener
來接收訊息,讓存在外部網頁的 main.js 可以 與 Extension 進行溝通 。
在Manifest中聲明 externally_connectable
主要目的為可以指定要與哪些網站或 其他Extension 來進行溝通傳遞資料,matches
為指定網址,ids
為指定 Extension ID,但如果將 "ids" 設為 ["*"]
時,則是所有外部 Extension 與應用程式都無法連接。
"externally_connectable": {
"matches": ["https://*.example.com/*"]
}
這邊需注意, 假使未在Manifest清單聲明 externally_connectable
時,除了網頁無法連接之外,其他外部的 Extension 與應用程式都可以與其連接。
接著,在Day 15 Message Passing跨Extension間的傳遞中,我們有提到要與外部Extension 傳遞訊息時,傳遞訊息方只能由Content Script方來發起,同時需透過 chrome.runtime.onMessageExternal.addListener()
在 Background 或 其他 Context 來進行接收。
發送端: Contnet Script 中的 Main.js
// main.js
let editorExtensionId = XXXX;
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
function(response) {
if (!response.success)
handleError(url);
});
接收端: Contnet Script 中的 Main.js
// main.js
chrome.runtime.onMessageExternal.addListener((request, sender, sendResponse)=>{
// do somethings
});
透過以上方法,也就可以達到與Extension 相互傳遞訊息的效果了。
說到這,chrome.onMessage 能透過 繞道的方式來使用,那...chrome.Storage 也可以吧?
有點抱歉...目前尚未找到可以直接在外部網頁中存取 chrom.storage
的方法,唯一繞道的方法 只能透過 sendMessage 來進行傳遞再透過 Background 事件來儲取 extension 的 storage 相關資料。
但但但,別擔心在下篇文章中 我們會介紹另一個方法可以在content script中使用 ES6 Module的方法,再請各位期待下。
以上就是關於 如何在 Content Script 中使用 ES6 Module 補充說明篇,那今天文章先到這邊了,謝謝願意花時間看此篇文章的你,如果文章有錯誤的地方,再麻煩不吝嗇的給予指教,感謝!!
今天推薦 -> 軌跡