【问题标题】:Serving files from static url with Go / Negroni / Gorilla Mux使用 Go / Negroni / Gorilla Mux 从静态 url 提供文件
【发布时间】:2015-06-09 01:52:07
【问题描述】:

所以我是 Go 新手,并尝试构建一个简单的 Web 服务器。我遇到的一个问题是我想使用动态静态 url 提供静态文件(以启用浏览器的长缓存)。例如,我可能有这个网址:

/static/876dsf5g87s6df5gs876df5g/application.js

但我想提供位于以下位置的文件:

/build/application.js

我将如何使用 Go / Negroni / Gorilla Mux 来解决这个问题?

【问题讨论】:

    标签: go gorilla negroni


    【解决方案1】:

    我知道为时已晚,但也许我的回答也会对某人有所帮助。我找到了一个库go-staticfiles,它通过向文件名添加哈希来实现静态文件缓存和版本控制。因此,可以为资产文件设置长时间缓存,并在它们更改时立即获得新副本。也很容易实现模板功能,将静态文件{{static "css/style.css"}}的链接转换为真实路径/static/css/style.d41d8cd98f00b204e9800998ecf8427e.css。在README中阅读更多示例

    【讨论】:

      【解决方案2】:

      您是否已经决定如何记录/保留 URL 的“随机”部分? D B?在内存中(即不跨重启)?如果没有,crypto/sha1 启动时的文件,并将生成的 SHA-1 哈希存储在 map/slice 中。

      否则,像(假设是大猩猩)r.Handle("/static/{cache_id}/{filename}", YourFileHandler) 这样的路线会起作用。

      package main
      
      import (
          "log"
          "mime"
          "net/http"
          "path/filepath"
      
          "github.com/gorilla/mux"
      )
      
      func FileServer(w http.ResponseWriter, r *http.Request) {
          vars := mux.Vars(r)
          id := vars["cache_id"]
      
          // Logging for the example
          log.Println(id)
      
          // Check if the id is valid, else 404, 301 to the new URL, etc - goes here!
          // (this is where you'd look up the SHA-1 hash)
      
          // Assuming it's valid
          file := vars["filename"]
      
          // Logging for the example
          log.Println(file)
      
          // Super simple. Doesn't set any cache headers, check existence, avoid race conditions, etc.
          w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(file)))
          http.ServeFile(w, r, "/Users/matt/Desktop/"+file)
      }
      
      func IndexHandler(w http.ResponseWriter, r *http.Request) {
          w.Write([]byte("Hello!\n"))
      }
      
      func main() {
      
          r := mux.NewRouter()
      
          r.HandleFunc("/", IndexHandler)
          r.HandleFunc("/static/{cache_id}/{filename}", FileServer)
      
          log.Fatal(http.ListenAndServe(":4000", r))
      }
      

      这应该可以开箱即用,但我不能保证它已经准备好投入生产。就个人而言,我只是使用 nginx 来提供我的静态文件,并从它的文件处理程序缓存、可靠的 gzip 实现等中受益。

      【讨论】:

      • 这就是我要找的。我将路线路径线调整为看起来像myMux.HandleFunc("/static/{cache_id}/{filename:[a-zA-Z0-9\\.\\-\\_\\/]*}", FileServer),以便能够处理像/static/8s7df65g87sd6f5g/app/test.html 这样的深层路径。我也同意在生产中,我将通过 nginx 之类的东西为 Go 应用程序提供服务,这将能够更好地处理这类事情,但是这个应用程序被设计为一个快速开发服务器(比 python SimpleHTTPServer 更好的东西) .谢谢。