教程:迁移到 Manifest V2

Manifest 版本 1 已在 Chrome 18 中被废弃,并且将根据 Manifest 版本 1 支持时间表逐步停止支持。从版本 1 到版本 2 的更改分为两大类:API 更改和安全更改。

本文档提供了将 Chrome 扩展程序从 Manifest 版本 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 更改摘要

Manifest 版本 2 对浏览器操作和页面操作 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 已被移除,并替换为新的对应项:

  • background_page 属性已替换为 background
  • chrome.self 属性已被移除,请使用 chrome.extension
  • Port.tab 属性已替换为 Port.sender
  • chrome.extension.getTabContentses()chrome.extension.getExtensionTabs() API 已 替换为 chrome.extension.getViews( { "type" : "tab" } )

安全更改摘要

从 Manifest 版本 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'",
      ...
    }
    

使用动态脚本评估

或许,新 Manifest V2 架构中最大的变化之一是,扩展程序无法再使用动态脚本评估技术(例如 eval() 或新的 Function()),或者将 JS 代码字符串传递给会导致使用 eval() 的函数(例如 setTimeout())。此外,某些常用的 JavaScript 库(例如 Google 地图和某些模板库)已知会使用其中一些技术。

Chrome 为页面提供了一个沙盒,以便页面在其自己的来源中运行,这些来源被拒绝访问 chrome.* API。如需在新内容安全政策下使用 eval() 等:

  1. 在清单文件中创建沙盒条目。
  2. 在沙盒条目中,列出要在沙盒中运行的页面。
  3. 使用通过 postMessage() 进行的消息传递与沙盒化页面通信。

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

深入阅读

Manifest 版本 2 中的更改旨在引导开发者构建更安全、架构更稳健的扩展程序和应用。如需查看从 Manifest 版本 1 到版本 2 的完整更改列表,请参阅清单文件文档。如需详细了解如何使用沙盒 隔离不安全的代码,请阅读沙盒化 Eval 文章。您可以访问我们的扩展程序相关教程和 HTML5Rocks 上的精彩介绍,详细了解内容 安全政策。