Linux 的自托管

Linux 是唯一一个 Chrome 用户可以安装不在 Chrome 应用商店托管的扩展程序的平台。本文介绍了如何从通用 Web 服务器打包、托管和更新 crx 文件。如果您仅通过 Chrome 应用商店分发扩展程序或主题,请参阅应用商店托管和更新

软件包

扩展程序和主题以 .crx 文件的形式提供。通过 Chrome 开发者信息中心上传时,信息中心会自动创建 crx 文件。如果发布到个人服务器,则需要在本地创建 crx 文件,或从 Chrome 网上应用店下载该文件。

从 Chrome 应用商店下载 .crx 文件

如果扩展程序托管在 Chrome 应用商店中,则可以从开发者信息中心下载 .crx 文件。在“您的列表”下找到该扩展程序,然后点击“了解详情”。在弹出式窗口中,点击蓝色的 main.crx 链接进行下载。

从开发者信息中心下载 .crx

下载的文件可以托管在个人服务器上。这是在本地托管扩展程序的最安全方式,因为扩展程序的内容将由 Chrome 应用商店进行签名。这有助于检测潜在的攻击和篡改行为。

在本地创建 .crx

扩展程序目录会在“扩展程序管理”页面上转换为 .crx 文件。前往 Omnibox 中的 chrome://extensions/,或点击 Chrome 菜单,将指针悬停在“更多工具”上,然后选择“扩展程序”。

在“扩展程序管理”页面上,点击开发者模式旁边的切换开关,以启用开发者模式。然后,选择 PACK EXTENSION(文件包扩展)按钮。

选中“开发者模式”,然后点击“打包扩展程序”

在“扩展程序根目录”字段中指定扩展程序文件夹的路径,然后点击 PACK EXTENSION 按钮。对于首次提交的软件包,请忽略私钥字段。

指定扩展程序路径,然后点击“打包扩展程序”

Chrome 将创建两个文件,一个 .crx 文件和一个 .pem 文件,其中包含扩展程序的私钥。

打包的扩展程序文件

请勿丢失私钥!请将 .pem 文件保存在秘密且安全的位置;您需要该文件来更新扩展程序。

更新 .crx 软件包

通过增加 manifest.json 中的版本号来更新扩展程序的 .crx 文件。

{
  ...
  "version": "1.5",
  ...
  }
}
{
  ...
  "version": "1.6",
  ...
  }
}

返回“扩展程序管理”页面,然后点击扩展程序包按钮。指定扩展程序目录的路径和私钥的位置。

更新扩展程序文件

该页面将提供更新后的打包扩展程序的路径。

更新扩展程序文件

通过命令行打包

通过调用 chrome.exe 在命令行中打包扩展程序。使用 --pack-extension 标志指定扩展程序文件夹的位置,并使用 --pack-extension-key 标志指定扩展程序的私钥文件的位置。

chrome.exe --pack-extension=C:\myext --pack-extension-key=C:\myext.pem

主机

托管 .crx 文件的服务器必须使用适当的 HTTP 标头,以允许用户通过点击链接安装扩展程序。

如果满足以下任一条件,Google Chrome 会将文件视为可安装:

  • 文件的类型为 application/x-chrome-extension
  • 文件后缀为 .crx,并且同时满足以下两个条件:
    • 文件使用 HTTP 标头 X-Content-Type-Options: nosniff 传送
    • 文件使用以下内容类型之一提供:
    • 空字符串
    • "text/plain"
    • "application/octet-stream"
    • "unknown/unknown"
    • "application/unknown"
    • "\*/\*"

无法识别可安装文件的最常见原因是服务器发送了标头 X-Content-Type-Options: nosniff。第二个最常见的原因是服务器发送了未知的内容类型(即上一个列表中未列出的内容类型)。如需解决 HTTP 标头问题,请更改服务器的配置,或尝试在其他服务器上托管 .crx 文件。

更新

浏览器每隔几小时就会检查已安装的扩展程序是否有更新网址。它会针对每个网址发出请求,以查找更新清单 XML 文件。

  • 更新检查返回的内容是一个更新清单 XML 文档,其中列出了扩展程序的最新版本。

如果更新清单中提及的版本高于已安装的版本,浏览器会下载并安装新版本。与手动更新一样,新 .crx 文件必须使用与当前安装版本相同的私钥进行签名。

注意:为了保护用户隐私,Google Chrome 不会随自动更新清单请求发送任何 Cookie 标头,并会忽略对这些请求的响应中的任何 Set-Cookie 标头。

更新网址

如果扩展程序托管在 Chrome 应用商店之外的服务器上,则必须在其 manifest.json 文件中包含 update_url 字段。

{
  "name": "My extension",
  ...
  "update_url": "https://myhost.com/mytestextension/updates.xml",
  ...
}

更新清单

服务器返回的更新清单应为 XML 文档。

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>
    <updatecheck codebase='https://myhost.com/mytestextension/mte_v2.crx' version='2.0' />
  </app>
</gupdate>

此 XML 格式借用了 Google 的更新基础架构 Omaha 所使用的格式。扩展程序系统会对更新清单的 <app><updatecheck> 元素使用以下属性:

appid
扩展程序 ID 基于公钥的哈希值生成,如打包中所述。扩展程序的 ID 显示在“扩展程序管理”页面上。
代码库
指向 .crx 文件的 HTTPS 网址。
版本
客户端使用此属性来确定是否应下载 codebase 指定的 .crx 文件。它应与 .crx 文件的 manifest.json 文件中的“version”值一致。

更新清单 XML 文件可以通过包含多个 <app> 元素来包含有关多个扩展程序的信息。

测试

默认的更新检查频率为几小时,但您可以使用“附加信息管理”页面上的立即更新附加信息按钮强制更新。

立即更新扩展程序

系统会开始检查所有已安装的扩展程序。

高级用法:请求参数

基本的自动更新机制旨在使服务器端工作变得简单,就像将静态 XML 文件放到任何普通 Web 服务器(如 Apache)上,并在新的扩展版本发布时更新该 XML 文件。

托管多个扩展程序的开发者可以检查请求参数,这些参数用于指明更新请求中的扩展程序 ID 和版本。添加这些参数可让扩展程序从运行动态服务器端代码(而非静态 XML 文件)的同一网址进行更新。

请求参数的格式为:

?x=EXTENSION_DATA

其中,EXTENSION_DATA 是以下格式的网址编码字符串:

id=EXTENSION_ID&v=EXTENSION_VERSION

例如,两个扩展程序指向同一个更新网址 (https://test.com/extension_updates.php):

  • 扩展程序 1
    • ID:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    • 版本:“1.1”
  • 扩展程序 2
    • ID:“bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb”
    • 版本:“0.4”

更新每个单独扩展程序的请求如下所示:

https://test.com/extension_updates.php?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%26v%3D1.1

https://test.com/extension_updates.php?x=id%3Dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%26v%3D0.4

在针对每个唯一更新网址的单个请求中,可以列出多个扩展程序。对于前面的示例,如果用户安装了这两个扩展程序,则这两个请求会合并为单个请求:

https://test.com/extension_updates.php?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%26v%3D1.1&x=id%3Dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%26v%3D0.4

如果使用同一更新网址的已安装扩展程序数量过多,导致 GET 请求网址过长(超过 2000 个字符),更新检查会在必要时发出其他 GET 请求。

高级用法:最低浏览器版本

随着更多 API 添加到扩展程序系统,可能会发布仅适用于更高版本的浏览器的扩展程序的更新版本。虽然 Google Chrome 本身会自动更新,但大多数用户可能需要几天时间才能更新到任何给定的新版本。为确保给定更新仅适用于等于或高于特定版本的 Google Chrome 版本,请将“prodversionmin”属性添加到更新响应中的 <app> 元素。

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>
    <updatecheck codebase='http://myhost.com/mytestextension/mte_v2.crx' version='2.0' prodversionmin='3.0.193.0'/>
  </app>
</gupdate>

这样可以确保,只有当用户使用的是 Google Chrome 3.0.193.0 或更高版本时,才会自动更新到版本 2。