gorilla / mux golang缓存静态文件

问题描述 投票:2回答:1

我有一个go web应用程序,它提供静态HTML / JS / CSS文件,还有一些API端点。我注意到我的HTML / JS / CSS没有被缓存在浏览器上。例如,每次重新加载页面时,都会完全重新下载。

这是我需要设置的服务器端配置更改吗?我怎样才能通过Go和Gorilla Mux实现这一目标?

我正在使用Google App Engine,因此不可能使用Nginx。

这是我的main.go代码:

package main

import (
    "associations"
    "html/template"
    "net/http"
    "log"
    "io/ioutil"

    "github.com/gorilla/mux"
    "github.com/rs/cors"
    "google.golang.org/appengine"
    "google.golang.org/appengine/mail"
)

var index = template.Must(template.ParseFiles(
    "dist/index.html",
))

func init() {
    r := mux.NewRouter()
    r.HandleFunc("/", homeHandler)  
    r.HandleFunc("/api/{tenant}/certificates", associations.GetCertificate).Methods("GET")
    r.HandleFunc("/api/{tenant}/requests", associations.PostRequest).Methods("POST")

    // handle static files
    r.PathPrefix("/static/").Handler(
        http.StripPrefix("/static/", http.FileServer(http.Dir("dist/static/"))))

    r.NotFoundHandler = http.HandlerFunc(homeHandler) // work around for SPA serving index.html

    handler := cors.Default().Handler(r)
    http.Handle("/", handler)
}

编辑:这是@Topo建议的解决方案:

   // handle static files
        r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", 
CacheControlWrapper(http.FileServer(http.Dir("dist/static/")))))

    ....

func CacheControlWrapper(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Cache-Control", "max-age=2592000") // 30 days
        h.ServeHTTP(w, r)
    })
}
go gorilla
1个回答
3
投票

要告诉浏览器缓存文件,您需要告诉它多长时间,如果不是用户永远不会看到该文件的更新版本。

要做到这一点,只需在处理函数中设置Cache-Control标头:

w.Header().Set("Cache-Control", "max-age=3600")

使用Etag标头让浏览器知道何时有新版本的文件也是一个好主意。这样,您可以将文件缓存很长时间,并且仍然可以在用户可用时立即将新内容提供给用户:

etag := "some unique value"
w.Header().Set("Etag", etag)

每次文件更改时,您都需要使用不同的etag值。浏览器存储它并仅在etag与存储值不同时重新加载文件。您可以使用etag的文件名+修改日期之类的内容:

var modTime time.Time
fi, err := fh.Stat()
if err != nil {
    modTime = fi.ModTime()
} else {
    modTime = time.Now()
}
etag := "\"" + file + modTime.String() + "\""
w.Header().Set("Etag", etag)

你可以阅读qazxsw poi和qazxsw poi标题的mozilla文档。

如果您想避免为静态文件编写自己的处理函数,而是继续使用Cache-Control,则需要将其包装在处理程序中,该处理程序在编写响应之前设置标头。 Etag是关于包装Web处理程序的博客文章。

© www.soinside.com 2019 - 2024. All rights reserved.