如何使用 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 工程师热切希望收到您对分发 SXG 的反馈,地址为 webpackage-dev@chromium.org。 您还可以参与规范讨论,或向团队报告 bug。 您的反馈将极大地帮助标准化流程,并有助于解决实施问题。 谢谢!