如何使用 nginx 获取和分发 SXG 文件,以及子资源预提取的挑战。
作为 Signed HTTP Exchange (SXG) 分销商,您可以代表原始内容创作者提交 SXG 文件。支持 SXG 的网络浏览器会将此类 SXG 文件显示为来自原始内容创作者的文件。这样,您就可以在不侵犯隐私的情况下实现跨网站预加载。本指南介绍了如何正确分发 SXG。
跨浏览器支持
Chrome 目前是唯一支持 SXG 的浏览器。如需了解最新信息,请参阅由源签名的 HTTP 交换的“共识和标准化”部分。
获取 SXG 文件
在 Accept
请求标头中指定您希望服务器随请求一起返回 SXG 文件:
Accept: application/signed-exchange;v=b3,*/*;q=0.8
本指南假定您将 SXG 文件放在 /var/www/sxg
中。
传送简单的 SXG 文件
若要分发单个 SXG 文件,请附加以下标头:
Content-Type: application/signed-exchange;v=v3
X-Content-Type-Options: nosniff
配置 nginx
:
http {
...
types {
application/signed-exchange;v=b3 sxg;
}
add_header X-Content-Type-Options nosniff;
location / {
more_set_headers "Content-Type: application/signed-exchange;v=b3";
alias /var/www/sxg/;
try_files $uri.sxg $uri =404;
autoindex off;
}
...
将新配置加载到 nginx
中:
sudo systemctl restart nginx.service
nginx
将开始投放 SXG 文件。
当 Chrome 访问您的服务器时,该栏中会显示原始内容发布商的地址!
预提取子资源
大多数网页由多个子资源组成,例如 CSS、JavaScript、字体和图片。 没有内容创作者的私钥,就无法更改 SXG 的内容。这会导致浏览器尝试解析子资源时出现问题。
例如,假设 https://website.test/index.html
中的 index.html.sxg
有一个指向 https://website.test/app.js
的链接。当用户的浏览器从 https://distributor.test/example.com/index.html.sxg
收到 SXG 文件时,它会找到指向 https://website.test/app.js
的链接。浏览器可以在实际访问时直接提取 https://website.test/app.js
,但为了保护隐私,不应在预加载阶段执行此操作。
如果资源是在预加载阶段提取的,则内容创作者 (website.test
) 或许能够检测到请求资源的内容分销商 (distributor.test
)。
如果分销商希望通过自己的服务提供 app.js.sxg
,并尝试将 https://website.test/app.js
修改为分销商的该子资源版本(例如 https://distributor.test/website.test/app.js.sxg
),则会导致签名不匹配,并使 SXG 无效。
为了解决此问题,Chrome 现在提供了一项实验性 SXG 子资源预提取功能。您可以在 about://flags/#enable-sxg-subresource-prefetching
启用此功能。
若要使用子资源预提取功能,必须满足以下条件:
- 发布商必须在 SXG 中嵌入响应标头条目,例如:
link: <https://website.test/app.js>;rel="preload";as="script",<https://website.test/app.js>;rel="allowed-alt-sxg";header-integrity="sha256-h6GuCtTXe2nITIHHpJM+xCxcKrYDpOFcIXjihE4asxk="
。这用于指定可替换为 SXG 的特定完整性哈希的子资源。 - 分销商在分发 SXG 时必须附加响应标头,例如:
link: <https://distributor.test/website.test/app.js.sxg>;rel="alternate";type="application/signed-exchange;v=b3";anchor="https://website.test/app.js"
。这会指定app.js
的路径,并与子资源相对应。
第一个相对容易,因为 nginx-sxg-module
可以计算完整性哈希并将其嵌入到上游响应的链接标头中。但第二种方法更难,因为内容分销商必须知道 SXG 中的指定子资源。
如果除了 https://website.test/app.js
之外没有其他子资源,那么您只需在 nginx 配置中附加以下内容即可:
add_header link <https://distributor.test/website.test/app.js.sxg>;rel="alter...
但由于典型的网站包含大量子资源,因此这种情况很少见。此外,分销商在分发 SXG 文件时必须附加适当的锚链接标头。目前,没有简单的方法来解决此问题,敬请关注最新动态!
发送反馈
Chromium 工程师非常期待您通过 webpackage-dev@chromium.org 提供有关分发 SXG 的反馈。 您还可以加入规范讨论,或向团队报告 bug。 您的反馈将对标准化流程大有帮助,也有助于解决实现问题。 谢谢!