如何使用 nginx 获取和提供 SXG 文件,以及子资源预加载的挑战。
作为 签名 HTTP 交换 (SXG) 分发者,您可以代表原始内容创建者分发 SXG 文件。支持 SXG 的 Web 浏览器将显示此类 SXG 文件,如同它们是由原始内容创建者分发的一样。这使您能够实施跨站点预加载,而不会侵犯隐私。本指南向您展示如何正确分发 SXG。
跨浏览器支持
Chrome 目前是唯一支持 SXG 的浏览器。有关最新信息,请参阅 Origin-Signed HTTP Exchanges 的“共识和标准化”部分。
获取 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 的反馈。您也可以加入 规范讨论,或报告错误给团队。您的反馈将极大地帮助标准化过程,并有助于解决实施问题。谢谢!