为了账号安全,请及时绑定邮箱和手机立即绑定

Go webserver - 不要使用时间戳缓存文件

Go webserver - 不要使用时间戳缓存文件

Go
开心每一天1111 2021-11-22 18:42:41
我正在嵌入式系统上运行用 go 编写的网络服务器。如果有人降级了固件版本,index.html 的时间戳可能会倒退。如果 index.html 比以前的版本旧,服务器会发送一个 http 304 响应(未修改),并提供文件的缓存版本。网络服务器代码使用 http.FileServer() 和 http.ListenAndServe()。使用Posix命令修改index.html的时间戳可以轻松重现该问题 touchtouch -d"23:59" index.html重新加载页面,然后touch -d"23:58" index.html这次重新加载将在 index.html 上给出 304 响应。有没有办法防止基于时间戳的缓存?
查看完整描述

1 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

假设您的文件服务器代码类似于文档中的示例:


http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/static"))))

您可以编写一个处理程序,通过剥离 ETag 标头并设置Cache-Control: no-cache, private, max-age=0防止缓存(本地和上游代理)来设置适当的缓存标头以防止这种行为:


var epoch = time.Unix(0, 0).Format(time.RFC1123)


var noCacheHeaders = map[string]string{

    "Expires":         epoch,

    "Cache-Control":   "no-cache, private, max-age=0",

    "Pragma":          "no-cache",

    "X-Accel-Expires": "0",

}


var etagHeaders = []string{

    "ETag",

    "If-Modified-Since",

    "If-Match",

    "If-None-Match",

    "If-Range",

    "If-Unmodified-Since",

}


func NoCache(h http.Handler) http.Handler {

    fn := func(w http.ResponseWriter, r *http.Request) {

        // Delete any ETag headers that may have been set

        for _, v := range etagHeaders {

            if r.Header.Get(v) != "" {

                r.Header.Del(v)

            }

        }


        // Set our NoCache headers

        for k, v := range noCacheHeaders {

            w.Header().Set(k, v)

        }


        h.ServeHTTP(w, r)

    }


    return http.HandlerFunc(fn)

}

像这样使用它:


http.Handle("/static/", NoCache(http.StripPrefix("/static/", http.FileServer(http.Dir("/static")))))

注意:我最初在github.com/zenazn/goji/middleware 上写了这个,所以你也可以导入它,但这是一段简单的代码,我想为后代展示一个完整的例子!


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信