教學課程:遷移至 Manifest V2

Chrome 18 已淘汰資訊清單第 1 版,並將按照資訊清單第 1 版支援時間表逐步停止支援。第 1 版到第 2 版的變更可分為兩大類:API 變更和安全性變更。

本文提供檢查清單,協助您將 Chrome 擴充功能從資訊清單第 1 版遷移至第 2 版,並詳細說明這些變更的意義和原因。

API 變更檢查清單

  • 您是否使用 browser_actions 屬性或 chrome.browserActions API?

  • browser_actions 替換為單數的 browser_action 屬性。

  • chrome.browserActions 替換為 chrome.browserAction

  • icons 屬性替換為 default_icon

  • name 屬性替換為 default_title

  • popup 屬性替換為 default_popup (現在必須是字串)。

  • 您是否使用 page_actions 屬性或 chrome.pageActions API?

  • page_actions 替換為 page_action

  • chrome.pageActions 替換為 chrome.pageAction

  • icons 屬性替換為 default_icon

  • name 屬性替換為 default_title

  • popup 屬性替換為 default_popup (現在必須是字串)。

  • 你是否使用 chrome.self 屬性?

  • chrome.extension 取代。

  • 你是否使用 Port.tab 屬性?

  • Port.sender 取代。

  • 您是否使用 chrome.extension.getTabContentses()chrome.extension.getExtensionTabs() API?

  • chrome.extension.getViews( { "type" : "tab" } ) 取代。

  • 您的擴充功能是否使用背景網頁?

  • background_page 屬性替換為 background 屬性。

  • 新增包含網頁程式碼的 scriptspage 屬性。

  • 新增persistent屬性並設為 false,將背景網頁轉換為事件網頁

安全性變更檢查清單

  • 您是否在 HTML 網頁中使用行內指令碼區塊?

  • 移除 <script> 標記中包含的 JavaScript 程式碼,並將其置於外部 JavaScript 檔案中。

  • 您是否使用內嵌事件處理常式 (例如 onclick 等)?

  • 請從 HTML 程式碼中移除這些屬性,將其移至外部 JS 檔案,並改用 addEventListener()

  • 擴充功能是否會將內容指令碼插入網頁,並存取擴充功能套件中的資源 (例如圖片和指令碼)?

  • 定義 web_accessible_resources 屬性,並列出資源 (以及這些資源的個別內容安全政策,視需要)。

  • 擴充功能是否會嵌入外部網頁?

  • 定義 sandbox 屬性。

  • 您的程式碼或程式庫是否使用 eval()、新的 Function()innerHTMLsetTimeout(),或是以其他方式傳遞動態評估的 JS 程式碼字串?

  • 如要將 JSON 程式碼剖析為物件,請使用 JSON.parse()

  • 使用 CSP 友善的程式庫,例如 AngularJS

  • 在資訊清單中建立沙箱項目,並使用 postMessage() 與沙箱網頁通訊,在沙箱中執行受影響的程式碼。

  • 您是否載入外部程式碼,例如 jQuery 或 Google Analytics?

  • 建議您下載程式庫並封裝到擴充功能中,然後從本機套件載入。

  • 在資訊清單的「content_security_policy」部分,將提供資源的 HTTPS 網域加入許可清單。

API 異動摘要

資訊清單第 2 版對瀏覽器動作和頁面動作 API 進行了幾項變更,並以新版 API 取代舊版 API。

瀏覽器動作的變更

瀏覽器動作 API 導入了幾項命名變更:

  • browser_actionschrome.browserActions 屬性已由單數對應項目 browser_actionchrome.browserAction 取代。
  • 舊版 browser_actions 屬性底下有 iconsnamepopup 屬性。這些已由下列項目取代:

  • 瀏覽器動作徽章圖示的 default_icon

  • 將游標懸停在徽章上時,工具提示中顯示的文字default_name

  • 代表瀏覽器動作 UI 的 HTML 網頁 (現在必須是字串,不能是物件)default_popup

網頁動作異動

與瀏覽器動作的變更類似,網頁動作 API 也已變更:

  • page_actionschrome.pageActions 屬性已由單數對應項目 page_actionchrome.pageAction 取代。
  • 舊版 page_actions 屬性底下有 iconsnamepopup 屬性。這些已替換為:

  • 網頁動作徽章圖示的 default_icon

  • 將游標懸停在徽章上時,工具提示中顯示的文字default_name

  • default_popup,代表網頁動作的 UI (現在必須是字串,不能是物件)

已移除和變更的 API

我們移除了部分擴充功能 API,並以新的對應項目取代:

  • background_page 屬性已由 background 取代。
  • 已移除 chrome.self 屬性,請改用 chrome.extension
  • Port.tab 屬性已由 Port.sender 取代。
  • chrome.extension.getTabContentses()chrome.extension.getExtensionTabs() API 已由 chrome.extension.getViews( { "type" : "tab" } ) 取代。

安全性異動摘要

從資訊清單第 1 版遷移至第 2 版時,會有一連串與安全性相關的變更。其中許多異動都源自於 Chrome 採用內容安全政策;建議您進一步瞭解這項政策,掌握其影響。

不允許內嵌指令碼和事件處理常式

由於使用內容安全政策,您無法再使用與 HTML 內容內嵌的 <script> 標記。這些內容必須移至外部 JS 檔案。此外,系統也不支援內嵌事件處理常式。舉例來說,假設擴充功能中有下列程式碼:

<html>
<head>
  <script>
    function myFunc() { ... }
  </script>
</head>
</html>

這個程式碼會在執行階段導致錯誤。如要修正這個問題,請將 <script> 標記內容移至外部檔案,並使用 src='path_to_file.js' 屬性參照這些檔案。

同樣地,許多網頁開發人員常用的便利功能「內嵌事件處理常式」也不會執行。舉例來說,請考慮下列常見情況:

<body onload="initialize()">
<button onclick="handleClick()" id="button1">

這些 API 無法在 Manifest V2 擴充功能中使用。移除內嵌事件處理常式,將其放在外部 JS 檔案中,然後使用 addEventListener() 註冊事件處理常式。舉例來說,在 JS 程式碼中,請使用:

window.addEventListener("load", initialize);
...
document.getElementById("button1").addEventListener("click",handleClick);

這樣可更清楚地將擴充功能的行為與使用者介面標記分開。

嵌入內容

在某些情況下,擴充功能可能會嵌入可供外部使用的內容,或來自外部來源。

網頁中的擴充功能內容: 如果擴充功能內嵌的資源 (例如圖片、指令碼、CSS 樣式等) 會用於注入網頁的內容指令碼,您需要使用 web_accessible_resources 屬性將這些資源加入允許清單,外部網頁才能使用這些資源:

{
...
  "web_accessible_resources": [
    "images/image1.png",
    "script/myscript.js"
  ],
...
}

嵌入外部內容: 內容安全政策只允許從套件載入本機指令碼和物件,可防止外部攻擊者在擴充功能中導入不明程式碼。不過,有時您會想載入外部提供的資源,例如 jQuery 或 Google Analytics 代碼。方法有以下兩種:

  1. 在本機下載相關程式庫 (例如 jQuery),然後與擴充功能一起封裝。
  2. 您可以在資訊清單的「content_security_policy」部分,將 HTTPS 來源加入允許清單,以有限的方式放寬 CSP。如要加入 Google Analytics 等程式庫,請採取下列做法:

    {
      ...,
      "content_security_policy": "script-src 'self'
      https://ssl.google-analytics.com; object-src 'self'",
      ...
    }
    

使用動態指令碼評估

新版資訊清單 v2 配置最重大的變更之一,就是擴充功能無法再使用動態指令碼評估技術,例如 eval() 或新的 Function(),或將 JS 程式碼字串傳遞至會導致使用 eval() 的函式,例如 setTimeout()。此外,某些常用的 JavaScript 程式庫 (例如 Google 地圖和特定範本程式庫) 也會使用這些技術。

Chrome 會為網頁提供沙箱,讓網頁在自己的來源中執行,並拒絕存取 chrome.* API。如要在新版內容安全政策下使用 eval() 等項目,請按照下列步驟操作:

  1. 在資訊清單檔案中建立沙箱項目。
  2. 在沙箱項目中,列出要在沙箱中執行的網頁。
  3. 透過 postMessage() 傳遞訊息,與沙箱化網頁通訊。

如要進一步瞭解如何執行這項操作,請參閱「沙箱 Eval」說明文件。

延伸閱讀

資訊清單第 2 版的變更旨在引導開發人員建構更安全且架構健全的擴充功能和應用程式。如要查看從資訊清單第 1 版到第 2 版的完整異動清單,請參閱資訊清單檔案說明文件。如要進一步瞭解如何使用沙箱隔離不安全的程式碼,請參閱 sandboxing eval 一文。如要進一步瞭解內容安全政策,請參閱擴充功能相關教學課程,以及 HTML5Rocks 上的簡介