非 Chrome 应用商店托管的扩展程序只能由 Linux 用户安装。本文介绍了如何打包、托管和更新个人服务器中的 .crx
文件。如果仅通过 Chrome 应用商店分发扩展程序或主题,请参阅应用商店托管和更新。
包装
扩展程序和主题以 .crx
文件的形式提供。通过 Chrome 开发者信息中心上传时,信息中心会自动创建 .crx
文件。如果发布在个人服务器上,则需要在本地创建 .crx
文件或从 Chrome 应用商店下载。
从 Chrome 应用商店下载 .crx
如果某个扩展程序托管在 Chrome 应用商店中,您可以从开发者信息中心下载 .crx
文件。在“您的商家信息”下找到该扩展程序,然后点击“了解详情”。在弹出式窗口中,点击蓝色的 main.crx
链接进行下载。
下载的文件可托管在个人服务器上。这是在本地托管扩展程序的最安全方法,因为扩展程序的内容将由 Chrome 应用商店签名。这有助于检测潜在的攻击和篡改行为。
在本地创建 .crx
扩展程序目录会在“扩展程序管理”页面上转换为 .crx
文件。在 Ominibox 中转到 chrome://extensions/
,或点击 Chrome 菜单,将鼠标悬停在“更多工具”上,然后选择“扩展程序”。
在“扩展程序管理”页面上,点击开发者模式旁边的切换开关来启用开发者模式。然后选择打包附加信息按钮。
在“扩展程序根目录”字段中指定扩展程序文件夹的路径,然后点击打包扩展程序按钮。对于首次使用软件包,请忽略 Private key 字段。
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"
- “未知/未知”
- “application/unknown”
- "*/*"
- 文件不会使用 HTTP 标头
无法识别可安装文件的最常见原因是服务器发送了标头 X-Content-Type-Options: nosniff
。第二个最常见的原因是服务器发送的内容类型未知,即不在上一个列表中。如需解决 HTTP 标头问题,请更改服务器的配置或尝试在其他服务器上托管 .crx
文件。
正在更新
浏览器每隔几小时就会检查已安装的扩展程序,看是否有更新网址。对于每个函数,它会向该网址发出请求,以查找更新清单 XML 文件。
- 更新检查返回的内容是一个更新清单 XML 文档,其中列出了相应扩展程序的最新版本。
如果更新清单提及的版本高于安装的版本,浏览器就会下载并安装新版本。与手动更新一样,必须使用与当前已安装的版本相同的私钥为新的 .crx
文件签名。
更新网址
在 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:“aaaaaaaaaaaaaaaaaaaaaaaaaaaaa”
- 版本:“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 可能会发布扩展程序的更新版本,该版本只适用于较新版本的浏览器。虽然 Google Chrome 本身是自动更新的,但大部分用户可能需要几天的时间才能更新到任何指定的新版本。要确保指定的更新仅应用于不低于特定版本的 Google Chrome,请将“prodversionmin”属性添加到更新响应中的
<?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。