iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Modern Web

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

# 你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 10 Content Script

  • 分享至 

  • xImage
  •  

Hi Dai Gei Ho~ 我是Winnie ~

https://ithelp.ithome.com.tw/upload/images/20220910/20139636ZZAv7244jZ.jpg

首先 大家中秋節快樂,在此篇文章中 我們要來介紹 Chrome Extension 中 的 Content Script ,雖然 前面已經有初步介紹過了,在今天文章內容中 預計會再針對其詳細內容及常見方法應用 進行補充。

關於 Content Script

如果大家有印象,Content Script 是 Extension 中唯一執行於 瀏覽器端 的 Context ,可以直接訪問 網頁中的資訊 且對DOM元素進行操作,同時又不會與頁面或其他Extension的內容腳本發生衝突。

這是為什麼呢 ?


截自:Google Chrome Extensions: Content Scripts and Isolated Worlds

雖然 Content Script 看似與網站的 JavaScript 共用,但其主要運行於 isolated worlds,所以基本上兩個是完全隔離的。

因為isolated worlds 為一個私有Javascript執行環境,雖然它允許 Javascript 透過DOM取得view(視圖),但不能使用相關 window.xxx()方法,所以兩者唯一共享的只有 HTML 中 DOM的View,不會互相產生程式碼衝突。

好像有點饒口,那讓我們以下程式範例為例:

這是一個 example.com的頁面,當在頁面中點擊helloBtn時,
原本頁面 會跳出 Good Morning ! Winnie 的 Alert :

// https://example.com
<html>
  <button id="helloBtn">click me</button>
  <script>
    const greeting = "Good Morning ! ";
    const button = document.getElementById("mybutton");
    button.person_name = "Winnie";
    button.addEventListener("click", () =>
      alert(greeting + button.person_name + ".")
    , false);
  </script>
</html>

接著,當 Extension 將Content Script 注入example.com的頁面

const greeting = "早上好, ";
const button = document.getElementById("mybutton");
button.person_name = "維尼";
button.addEventListener("click", () =>
  alert(greeting + button.person_name + ".")
, false);

此時的結果會分別出現Good Morning ! Winnie早上好 !維尼 兩個Alert。 同時 我們宣告的 greeting、 button 變數在console中也沒出現重複宣告的錯誤。

Content Script 的限制

Content Script 除了不能直接使用頁面中window.xxx之外,因為安全性考量,在眾多 Chrome API 中使用也有所限制,目前可以直接使用的方法有:

  • chrome.i18n
  • storage
  • chrome.runtime : connectgetManifestgetURLidonConnectonMessagesendMessage``

關於 Chrome API 方法的使用,因為後續會有獨立文章進行說明,當全系列文章結束後會再添加對應連結,所以在這邊就先不進行說明了

注入 Scripts 的 方式

關於 Content Script 注入方式有兩種, 分別是: Declaration InjectionDynamic Injection

Declaration Injection

關於 Declaration Inject,想必看過前面的篇章中的範例的捧油們,應該很熟悉了。其主要方式就是在 Manifest.json 中提前定義好所要注入網站中執行的程式檔,其中可以包括 Javascript、css檔。

指定注入頁面

其中 match 欄位為指定此內容腳本將被注入到哪些頁面,為必填欄位。

載入時機

run_at 欄位為指定何時將Cotent Script程式 注入於頁面中,分別有三個選項: document_idledocument_startdocument_end

其中"document_idle"為預設值,同時。

  // manifest.json
  
  "content_scripts": [
    {
      "matches": [
        "https://ithelp.ithome.com.tw/users/20139636"
      ],
      "js": [
        "/content_script/content.js"
      ],
      "css":[
        "/style/content.css"
      ],
      run_at: 'document_start
    }
  ]

Dynamic Injection

相較於前一個靜態注入 Content Scripts。

Dynamic Injection 的使用方式較為 被動, 同常注入Scripts時機為 當特定事件觸發時

什麼意思呢?

假設 當 Background 背景事件 監聽到 使用者點擊了Notification的訊息事件時,想要讓 當前網頁即時跳出Extension 通知視窗時,就可以 Dynamic Injection 方式將Script 注入到當前頁面中,而提前就將通知視窗顯示出來。

使用方式如下:

首先,因為要注入Scripts,所以需請求權限,在 Manifest 的 Permission 中 聲明 scripting

  // Manifest.json
  {
      "permissions": [ "scripting", activeTab, tab],
  }

注入檔案:

接著 透過chrome.scripting.executeScript方法將 JavaScript 檔案 注入 到 指定的 TabId中。

關於 Tab API 及 相關監聽事件的用法,在後續Chrome 常見API方法篇 也會介紹到,同樣地後續會再補上連結...

//background.js

chrome.notifications.onClicked.addListener(
const tabId = getTabId();
chrome.scripting.executeScript(
    {
      target: {tabId: tabId},
      files: ['script.js'],
    },
    () => { ... });
)

注入Function:

除了以檔案方式注入,也可以Functionc方式注入,同時如需要傳遞參數可以args 欄位以Array方式來宣告。

//background.js

function injectedFunction(msg, from) {
  // 略..
  console.log(msg, from)
}

chrome.notifications.onClicked.addListener(
const tabId = getTabId();
chrome.scripting.executeScript(
    {
        target: { tabId: tab.id },
        matches: ["https://*.nytimes.com/*"],
        function: injectedFunction
        args:['中秋節快樂!', 'from Winnie']
    },
    () => { ... });
)

到了這邊,其實在官網文件中還有提供更多 Content Script 注入的方法細節可以使用,但因為內容真的太雜,所以就挑了幾個經常使用到的來進行介紹,如果有興趣的朋友可以再去文件尋寶尋寶

以上就是關於 Content Script 運作與常見應用的介紹,而在下一篇我們將 介紹 Extension中的 UI Popup

那今天文章先到這邊了,謝謝願意花時間看此篇文章的你,如果文章有錯誤的地方,再麻煩不吝嗇的給予指教,感謝!!

今日有感而發:

鐵人賽真的很神奇,讓我感覺每天都有被時間追著跑的感覺
雖然我現在 有點累、有點崩潰、甚至已經不知道後面再打什麼了
但卻沒有想要放棄...
才發現原來我是M派啊 我說麥當勞好吃的部分
今天想分享一首 -> 如常


上一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day9 Background 事件監聽器
下一篇
# 你知道這是什麼嗎? Chrome extension MV3 With Vite - Day 11 用 Action 操作 Extension UI 吧 (上)
系列文
你知道這是什麼嗎? Chrome Extension MV3 With Vite30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言