为 go:embed 嵌入的资源开启条件缓存

💡 原文中文,约4000字,阅读约需10分钟。
📝

内容提要

本文讨论了如何为Go语言中的go:embed嵌入资源开启条件缓存。通过HTTP条件请求,服务器可以利用文件的Last-Modified或ETag信息判断资源是否更新,从而减少数据传输。由于go:embed嵌入的文件失去了修改时间,作者提出了两种解决方案:使用服务启动时间或源代码最近提交时间。此外,扩展了fs.FS接口以支持条件请求,但尚未实现基于ETag的条件请求。

🎯

关键要点

  • 使用 go:embed 嵌入资源后,文件失去了修改时间,导致无法利用 HTTP 条件缓存。
  • HTTP 条件请求通过 Last-Modified 和 ETag 头信息来判断资源是否更新。
  • 为解决 go:embed 的修改时间问题,提出两种方案:使用服务启动时间或源代码最近提交时间。
  • 扩展 fs.FS 接口以支持条件请求,但目前尚未实现基于 ETag 的条件请求。
  • 通过封装 fs.FS 和 fs.File 对象,可以实现自定义的文件修改时间返回。

延伸问答

如何为Go语言中的go:embed嵌入资源开启条件缓存?

可以通过扩展fs.FS接口,使用服务启动时间或源代码最近提交时间作为文件的修改时间来实现条件缓存。

go:embed嵌入的文件为什么失去了修改时间?

因为通过go:embed嵌入的文件内容与文件系统无关,因此失去了创建时间和修改时间等信息。

HTTP条件请求是如何工作的?

HTTP条件请求通过Last-Modified和ETag头信息来判断资源是否更新,若未更新则返回304 Not Modified状态码。

使用Last-Modified和ETag的场景有什么不同?

Last-Modified适用于静态文件,而ETag适用于动态生成的内容或内容变化但文件不变的情况。

如何扩展fs.FS接口以支持条件请求?

可以通过自定义embedFS结构体,重写Open()和Stat()函数来返回指定的文件修改时间。

目前Go语言是否支持基于ETag的条件请求?

目前不支持,因为os.FileInfo实现中不支持返回文件内容摘要值,但有提案希望引入HashFileInfo接口。

➡️

继续阅读