iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Modern Web

你知道這是什麼嗎? Chrome Extension MV3 With Vite系列 第 22

你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 22 Content Script 中使用 ES6 Module (補充說明篇)

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20220922/20139636VQDG8DFlOd.jpg

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.addListenerruntime.sendMessage來傳遞就好了,還不用指定tab不是超讚超方便!

wait~wait~wait~ 因為執行環境的原因,還是無法使用。

那這樣 要怎麼與Extension來傳遞訊息呢?

可以,只是要繞道而行

在Extension相關方法中,有提供 externally_connectable權限 搭配在後台 監聽chrome.runtime.onMessageExternal.addListener 來接收訊息,讓存在外部網頁的 main.js 可以 與 Extension 進行溝通 。

externally_connectable

在Manifest中聲明 externally_connectable 主要目的為可以指定要與哪些網站或 其他Extension 來進行溝通傳遞資料,matches為指定網址,ids為指定 Extension ID,但如果將 "ids" 設為 ["*"]時,則是所有外部 Extension 與應用程式都無法連接。

"externally_connectable": {
  "matches": ["https://*.example.com/*"]
}

這邊需注意, 假使未在Manifest清單聲明 externally_connectable時,除了網頁無法連接之外,其他外部的 Extension 與應用程式都可以與其連接。

onMessageExternal

接著,在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 相互傳遞訊息的效果了。


Storage

說到這,chrome.onMessage 能透過 繞道的方式來使用,那...chrome.Storage 也可以吧?

有點抱歉...目前尚未找到可以直接在外部網頁中存取 chrom.storage的方法,唯一繞道的方法 只能透過 sendMessage 來進行傳遞再透過 Background 事件來儲取 extension 的 storage 相關資料。

但但但,別擔心在下篇文章中 我們會介紹另一個方法可以在content script中使用 ES6 Module的方法,再請各位期待下。

下篇連結

以上就是關於 如何在 Content Script 中使用 ES6 Module 補充說明篇,那今天文章先到這邊了,謝謝願意花時間看此篇文章的你,如果文章有錯誤的地方,再麻煩不吝嗇的給予指教,感謝!!

今天推薦 -> 軌跡


上一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 21 Extension 中的 ES6 Module
下一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 23 在 Content Script 中使用 Iframe
系列文
你知道這是什麼嗎? Chrome Extension MV3 With Vite30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言