尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Fiber 如何用 SendEarlyHints 发送 103 Early Hints 让浏览器预加载静态资源

Fiber 如何用 SendEarlyHints 发送 103 Early Hints 让浏览器预加载静态资源 Fiber 如何用 SendEarlyHints 发送 103 Early Hints 让浏览器预加载静态资源【免费下载链接】fiber⚡️ Express inspired web framework written in Go项目地址: https://gitcode.com/GitHub_Trending/fi/fiber当服务端需要一段时间才能生成最终响应时浏览器在响应到达前基本处于空等状态。Fiber v3 提供的SendEarlyHints方法可以在最终响应之前发送一个103 Early Hints信息响应其中携带一个或多个Link头让浏览器在服务端还在准备响应时就提前预加载页面所需的脚本、样式等资源。该功能对应 Fiber 的状态码常量StatusEarlyHints值为103RFC 8297定义见 docs/api/constants.md方法文档见 docs/api/ctx.md 的SendEarlyHints一节。方法签名与基本用法方法签名Ctx与Res上均可调用func (c fiber.Ctx) SendEarlyHints(hints []string) error func (r fiber.Res) SendEarlyHints(hints []string) errorhints参数的每个元素是一条Link头的值。官方文档给出的示例hints : []string{https://cdn.com/app.js; relpreload; asscript} app.Get(/early, func(c fiber.Ctx) error { if err : c.SendEarlyHints(hints); err ! nil { return err } return c.SendString(done) })调用SendEarlyHints后handler 照常返回最终响应即可。API 文档明确标注了前提条件该功能要求HTTP/2 或更新版本部分旧版 HTTP/1.1 客户端可能不支持sendEarlyHints会忽略这些中间响应或在收到它们时行为异常。用反向代理启用 HTTP/2反向代理指南 明确把SendEarlyHints列为需要 HTTP/2 或更新版本的功能并指出通过反向代理如 Nginx 或 Traefik启用是最简单的方式。Nginx 配置主路径关键点是在 443 端口上开启http2 on;由 Nginx 终结 TLS 并与客户端说 HTTP/2再转发给 Fiber 进程server { listen 443 ssl; http2 on; server_name example.com; ssl_certificate /etc/ssl/certs/example.crt; ssl_certificate_key /etc/ssl/private/example.key; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Connection ; proxy_set_header Host $host; # Overwrite untrusted inbound forwarding headers at the edge. proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; } }对应的 Fiber 进程监听 3000 端口示例代码取自仓库文档server_name、证书路径和/early路由中的资源地址按你自己的站点替换package main import ( log github.com/gofiber/fiber/v3 ) func main() { app : fiber.New() hints : []string{https://cdn.com/app.js; relpreload; asscript} app.Get(/early, func(c fiber.Ctx) error { if err : c.SendEarlyHints(hints); err ! nil { return err } return c.SendString(done) }) log.Fatal(app.Listen(:3000)) }备选Traefik指南同时给出 Traefik 配置按该配置 Traefik 会终结 TLS 并以 HTTP/2 对外提供服务entryPoints: websecure: address: :443 http: routers: app: rule: Host(example.com) entryPoints: - websecure service: app tls: {} services: app: loadBalancer: servers: - url: http://127.0.0.1:3000可选分支HTTP/3反向代理指南指出Early Hints103 响应可以在 HTTP/1.1 和 HTTP/2/3 上传送但实际上浏览器在 HTTP/2/3 上处理 103 最可靠Nginx 和 Traefik 都支持 HTTP/3QUIC。启用 HTTP/3 是可选的启用后 Early Hints 响应仍按预期工作。哪些请求收不到中间 103 响应API 文档列出了两个边界情况共同点是Link头仍会出现在最终响应上只是中间 103 不会被送达。非 HTTP/1.1 的请求例如 HTTP/1.0不会发送中间103响应——RFC 9110 禁止向 HTTP/1.0 客户端发送 1xx 响应——但Link头仍会包含在最终响应中。应用通过adaptor中间件挂载进net/http时没有可供写中间响应的客户端连接103会被静默跳过Link头仍随最终响应送达。从源码实现 res.go 可以看到对应逻辑先把hints中的每一项追加为当前响应的Link头如果请求不是 HTTP/1.1直接返回而不写中间响应只有 HTTP/1.1 连接才调用 fasthttp 的EarlyHints()真正写出 103。传入空的hints切片时方法直接返回nil不发送任何内容。验证检查最终响应中的 Link 头仓库自带测试 ctx_test.go 给出了可复现的验证方式对注册了 handler 的路由用app.Test发起请求断言最终响应的Link头等于传入的hintsfunc Test_Ctx_SendEarlyHints(t *testing.T) { t.Parallel() app : New() hints : []string{https://cdn.com; relpreload; asscript} app.Get(/earlyhints, func(c Ctx) error { err : c.SendEarlyHints(hints) require.NoError(t, err, SendEarlyHints) c.Status(StatusBadRequest) return c.SendString(fail) }) req : httptest.NewRequest(MethodGet, /earlyhints, http.NoBody) resp, err : app.Test(req) require.NoError(t, err, app.Test(req)) require.Equal(t, StatusBadRequest, resp.StatusCode, Status code) require.Equal(t, hints, resp.Header[Link], Link header) }这里的StatusBadRequest和fail是测试自身设置的随意值与SendEarlyHints真正相关的断言是最后一条——resp.Header[Link]与传入的hints一致。也就是说在中间 103 可能不被送达的任何环境如 HTTP/1.0、adaptor 挂载下都可以用“最终响应携带Link头”这一可核对的结果来判断 hint 已生效。针对 HTTP/1.0 场景Test_Ctx_SendEarlyHints_HTTP10 做了专门验证把请求协议设为HTTP/1.0后调用SendEarlyHints不会发送 103但c.GetRespHeader(HeaderLink)仍能读回完整的 hint 内容确认头已进入最终响应。需要注意SendEarlyHints与 EarlyData 中间件 是两件互不相关的事后者处理 TLS 1.3 的 0-RTT 早期数据前者处理103预加载提示启用 Early Hints 不需要引入 EarlyData。旧 HTTP/1.1 客户端可能忽略或不一致地处理这些中间响应docs/whats_new.md 的说法它不会阻断最终响应Link头仍会随最终响应到达浏览器。【免费下载链接】fiber⚡️ Express inspired web framework written in Go项目地址: https://gitcode.com/GitHub_Trending/fi/fiber创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表