教學課程:遷移至 Manifest V2

在 Chrome 18 中,Manifest 1 已淘汰,並將依據Manifest 1 支援時間表逐步淘汰。從第 1 版到第 2 版的變更可分為兩大類別:API 變更和安全性變更。

本文件提供檢查清單,說明如何將 Chrome 擴充功能從資訊清單 1 版遷移至 2 版,並進一步說明這些變更的意義和原因。

API 變更檢查清單

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

  • browser_actions 替換為單數 browser_action 屬性。

  • chrome.browserAction 取代 chrome.browserActions

  • icons 屬性替換為 default_icon

  • name 屬性替換為 default_title

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

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

  • page_action 取代 page_actions

  • chrome.pageAction 取代 chrome.pageActions

  • 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> 標記內含的 JS 程式碼,並將其放入外部 JS 檔案中。

  • 您是否使用內嵌事件處理常式 (例如 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.0 版對瀏覽器動作和網頁動作 API 進行了一些變更,並將部分舊 API 替換為新 API。

瀏覽器動作的變更

瀏覽器動作 API 引進了一些名稱變更:

  • browser_actionschrome.browserActions 屬性已替換為單數形式的 browser_actionchrome.browserAction
  • 在舊版 browser_actions 屬性下,有 iconsnamepopup 屬性。已由下列項目取代:

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

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

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

網頁動作異動

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

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

  • default_icon:網頁動作徽章圖示

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

  • default_popup:代表網頁動作 UI 的 HTML 網頁 (目前必須是字串,不能是物件)

已移除及變更的 API

我們移除了部分擴充功能 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">

這些元素無法在 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() 傳遞的訊息,與沙箱頁面通訊。

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

延伸閱讀

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