【问题标题】:Serving static content with a root URL with the Gorilla toolkit使用 Gorilla 工具包通过根 URL 提供静态内容
【发布时间】:2013-03-27 21:20:26
【问题描述】:

我正在尝试使用 Gorilla 工具包的 mux package 在 Go Web 服务器中路由 URL。使用 this question 作为指导,我有以下 Go 代码:

func main() {
    r := mux.NewRouter()
    r.Handle("/", http.FileServer(http.Dir("./static/")))
    r.HandleFunc("/search/{searchTerm}", Search)
    r.HandleFunc("/load/{dataId}", Load)
    http.Handle("/", r)
    http.ListenAndServe(":8100", nil)
}

目录结构为:

...
main.go
static\
  | index.html
  | js\
     | <js files>
  | css\
     | <css files>

Javascript 和 CSS 文件在 index.html 中引用如下:

...
<link rel="stylesheet" href="css/redmond/jquery-ui.min.css"/>
<script src="js/jquery.min.js"></script>
...

当我在 Web 浏览器中访问 http://localhost:8100 时,index.html 内容已成功交付,但是,所有 jscss URL 都返回 404。

如何让程序从static 子目录中提供文件?

【问题讨论】:

  • 您可能希望看到有关从根目录或子目录提供静态文件stackoverflow.com/questions/14086063/… 的讨论(尽管不使用 Gorilla)
  • @Ripounet,我在研究过程中确实看到了这个问题,但是,由于它没有使用 Gorilla,所以我永远无法获得与我的目标之一没有的设置一起使用的想法我项目根目录中的所有静态文件(main.go 旁边)。此外,它似乎与下面的@Joe's answer 非常相似,这也不适用于我的设置。

标签: web-applications go mux


【解决方案1】:

我想你可能正在寻找PathPrefix...

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/search/{searchTerm}", Search)
    r.HandleFunc("/load/{dataId}", Load)
    r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
    http.ListenAndServe(":8100", r)
}

【讨论】:

  • 这很有帮助,谢谢。我确实在尝试让两个别名工作时遇到了问题。例如r.PathPrefix("/a/").Handler(http.FileServer(http.Dir("b/"))) r.PathPrefix("/").Handler(http.FileServer(http.Dir("c/"))) 在这种情况下,c/ 中的所有内容都会被提供,但b/ 不会。尝试了一些不同的微妙变化,但没有成功。有什么想法吗?
  • @markdsievers,您可能需要从 URL 中删除“/a/”部分。示例:r.PathPrefix("/a/").Handler(http.StripPrefix("/a/", http.FileServer(http.Dir("b")))).
  • 是否可以添加 NotFound 处理程序?
  • 该代码似乎与我当前的项目代码相似,只是需要注意:静态处理程序需要作为最后一个路由,否则other 路由的 GET 也会被该静态处理程序覆盖.
  • 这为我修好了!正如@HoangTran 提到的,您需要将其设置为最后一条路线。如果一切都失败了,基本上就像“包罗万象”。
【解决方案2】:

这将提供文件夹标志内的所有文件,以及在根目录提供 index.html。

用法

   //port default values is 8500
   //folder defaults to the current directory
   go run main.go 

   //your case, dont forget the last slash
   go run main.go -folder static/

   //dont
   go run main.go -folder ./

代码

    package main

import (
    "flag"
    "fmt"
    "net/http"
    "os"
    "strconv"
    "strings"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
    "github.com/kr/fs"
)

func main() {
    mux := mux.NewRouter()

    var port int
    var folder string
    flag.IntVar(&port, "port", 8500, "help message for port")
    flag.StringVar(&folder, "folder", "", "help message for folder")

    flag.Parse()

    walker := fs.Walk("./" + folder)
    for walker.Step() {
        var www string

        if err := walker.Err(); err != nil {
            fmt.Fprintln(os.Stderr, "eroooooo")
            continue
        }
        www = walker.Path()
        if info, err := os.Stat(www); err == nil && !info.IsDir() {
            mux.HandleFunc("/"+strings.Replace(www, folder, "", -1), func(w http.ResponseWriter, r *http.Request) {
                http.ServeFile(w, r, www)
            })
        }
    }
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, folder+"index.html")
    })
    http.ListenAndServe(":"+strconv.Itoa(port), handlers.LoggingHandler(os.Stdout, mux))
}

【讨论】:

    【解决方案3】:

    我这里有这段代码,效果很好,可以重复使用。

    func ServeStatic(router *mux.Router, staticDirectory string) {
        staticPaths := map[string]string{
            "styles":           staticDirectory + "/styles/",
            "bower_components": staticDirectory + "/bower_components/",
            "images":           staticDirectory + "/images/",
            "scripts":          staticDirectory + "/scripts/",
        }
        for pathName, pathValue := range staticPaths {
            pathPrefix := "/" + pathName + "/"
            router.PathPrefix(pathPrefix).Handler(http.StripPrefix(pathPrefix,
                http.FileServer(http.Dir(pathValue))))
        }
    }
    router := mux.NewRouter()
    ServeStatic(router, "/static/")
    

    【讨论】:

      【解决方案4】:

      经过大量试验和错误,以上两个答案都帮助我想出了对我有用的方法。我在网络应用程序的根目录中有静态文件夹。

      PathPrefix 一起,我不得不使用StripPrefix 来获取路线以递归方式工作。

      package main
      
      import (
          "log"
          "net/http"
          "github.com/gorilla/mux"
      )
      
      func main() {
          r := mux.NewRouter()
          s := http.StripPrefix("/static/", http.FileServer(http.Dir("./static/")))
          r.PathPrefix("/static/").Handler(s)
          http.Handle("/", r)
          err := http.ListenAndServe(":8081", nil)
      }
      

      我希望它可以帮助其他有问题的人。

      【讨论】:

      • 对于使用golang workspace s := ... 的任何人,当您的工作目录为[workspace]/src ... s := http.StripPrefix("/static/", httpFileServer(http.Dir("./web/static/"))) 时,应如下所示
      • 我认为,您也可以使用一些“github.com/lpar/gzipped”或类似的库来 gZip 静态内容。 gzipped.FileServer(http.Dir("./static/"))
      • 它对我不起作用,我找不到 404 页面
      【解决方案5】:

      试试这个:

      fileHandler := http.StripPrefix("/static/", http.FileServer(http.Dir("/absolute/path/static")))
      http.Handle("/static/", fileHandler)
      

      【讨论】:

      • 这意味着将所有srchref 等属性更改为"/static/js/jquery.min.js" 形式。虽然技术上工作。
      • 这将允许加载 JS 和 CSS 文件,但 index.html 文件在 http://localhost:8100/ 将不再可用
      • 我一般把images,css,js等都放在static文件夹里。
      • 首页的内容通常是动态生成的。
      • 如果主页通过 JavaScript 拉取所有动态内容,那么 index.html 本身通常是完全静态的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2015-06-09
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 2018-11-12
      • 2012-04-27
      相关资源
      最近更新 更多