教程:迁移到 Manifest V2

清单版本 1 在 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> 标记中包含的 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 替换为新 API。

浏览器操作变更

浏览器操作 API 引入了一些命名变化:

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

  • default_icon 表示浏览器操作标记图标

  • default_name:适用于将鼠标悬停在标记上时显示在提示中的文本

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

页面操作的变化

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

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

  • default_icon,表示页面操作标记图标

  • default_name:适用于将鼠标悬停在标记上时显示在提示中的文本

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

已移除和更改了的 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' 属性引用这些内容。

同样,内嵌事件处理脚本也不会执行,很多 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 简介