教程:迁移到 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.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> 标记中包含的 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 对浏览器操作和网页操作 API 进行了一些更改,并将一些旧 API 替换为了新 API。

浏览器操作的更改

BrowserActions API 引入了一些命名变更:

  • browser_actionschrome.browserActions 属性已替换为其单数形式 browser_actionchrome.browserAction
  • 在旧版 browser_actions 属性下,有 iconsnamepopup 属性。已替换为:

  • default_icon(用于浏览器操作标志图标)

  • default_name(用于显示在您将鼠标悬停在徽章上时在提示中显示的文本)

  • default_popup(用于表示浏览器操作界面的 HTML 页面,此值现在必须为字符串,不能为对象)

对网页操作所做的更改

与浏览器操作的更改类似,网页操作 API 也发生了变化:

  • page_actionschrome.pageActions 属性已替换为其单数形式 page_actionchrome.pageAction
  • 在旧版 page_actions 属性下,有 iconsnamepopup 属性。已替换为:

  • default_icon(网页操作标记图标)

  • default_name(用于显示在您将鼠标悬停在徽章上时在提示中显示的文本)

  • 表示网页操作界面的 HTML 网页的 default_popup(此值现在必须是字符串,不能是对象)

已移除和更改的 API

移除了一些扩展程序 API,并将其替换为新的 API:

  • background_page 属性已替换为背景
  • 移除了 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' 属性引用它们。

同样,许多 Web 开发者常用的内嵌事件处理程序(一种常见且便捷的功能)也不会执行。例如,请考虑以下常见情况:

<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() 传递消息的方式与沙盒化页面通信。

如需详细了解如何执行此操作,请参阅沙盒化评估文档。

深入阅读

清单版本 2 中的变更旨在引导开发者构建架构更安全、更稳健的扩展程序和应用。如需查看从清单版本 1 到版本 2 的完整变更列表,请参阅清单文件文档。如需详细了解如何使用沙盒隔离不安全的代码,请参阅沙盒评估一文。如需详细了解内容安全政策,请参阅我们与扩展程序相关的教程以及 HTML5Rocks 上的简介