Golang Gorilla mux 与 http.FileServer 返回 404
Posted
技术标签:
【中文标题】Golang Gorilla mux 与 http.FileServer 返回 404【英文标题】:Golang Gorilla mux with http.FileServer returning 404 【发布时间】:2014-02-09 15:51:07 【问题描述】:我看到的问题是我正在尝试将 http.FileServer
与 Gorilla mux Router.Handle 函数一起使用。
这不起作用(图像返回 404)..
myRouter := mux.NewRouter()
myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
这行得通(图像显示正常)..
http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
下面是简单的go web server程序,显示问题...
package main
import (
"fmt"
"net/http"
"io"
"log"
"github.com/gorilla/mux"
)
const (
HomeFolder = "/root/test/"
)
func HomeHandler(w http.ResponseWriter, req *http.Request)
io.WriteString(w, htmlContents)
func main()
myRouter := mux.NewRouter()
myRouter.HandleFunc("/", HomeHandler)
//
// The next line, the image route handler results in
// the test.png image returning a 404.
// myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
//
myRouter.Host("mydomain.com")
http.Handle("/", myRouter)
// This method of setting the image route handler works fine.
// test.png is shown ok.
http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
// HTTP - port 80
err := http.ListenAndServe(":80", nil)
if err != nil
log.Fatal("ListenAndServe: ", err)
fmt.Printf("ListenAndServe:%s\n", err.Error())
const htmlContents = `<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Test page</title>
<meta charset = "UTF-8" />
</head>
<body>
<p align="center">
<img src="/images/test.png" >
</p>
</body>
</html>
`
【问题讨论】:
【参考方案1】:我在 golang-nuts 讨论组上发布了这个并得到了this solution from Toni Cárdenas ...
标准的 net/http ServeMux(这是您在使用 http.Handle
时使用的标准处理程序)和 mux 路由器具有不同的地址匹配方式。
查看http://golang.org/pkg/net/http/#ServeMux 和http://godoc.org/github.com/gorilla/mux 之间的区别。
所以基本上,http.Handle('/images/', ...)
匹配'/images/whatever',而myRouter.Handle('/images/', ...)
仅匹配'/images/',如果你想处理'/images/whatever',你必须...
选项 1 - 在路由器中使用正则表达式匹配
myRouter.Handle("/images/rest",
http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))))
选项 2 - 在路由器上使用 PathPrefix 方法:
myRouter.PathPrefix("/images/").Handler(http.StripPrefix("/images/",
http.FileServer(http.Dir(HomeFolder + "images/"))))
【讨论】:
+1 #2 在我当前的项目中已经成功(在我偶然发现这个答案之前。只是向读者保证 #2 是我正在使用和工作的)。跨度> 只是补充说明,请记住,如果你是像我这样的 golang 新手,golang 不喜欢 #2 中格式化的语句。我需要在 golang 停止抱怨期待逗号之前将所有三行合并为一行(语法没有变化,只有空格的变化)。 #2 是正确的答案,它只是以这样的方式形成,会给像我这样的新手和新手带来问题。 你说得对,我不得不把 make 语句放在一行。 非常感谢您让我摆脱了数小时的痛苦,PathPrefix 和 StripPrefix 对我有用,我从r.Handle("/", fs)
转到 r.PathPrefix("/").Handler(http.StripPrefix("/", fs))
@SamGamgee - 你可以更进一步,删除http.StripPrefix()
,这样你最终会得到r.PathPrefix("/").Handler(fs)
【参考方案2】:
截至 2015 年 5 月,gorilla/mux 软件包仍然没有版本发布。但现在问题不同了。并不是myRouter.Handle
不匹配 url 并且需要正则表达式,它确实如此!但是http.FileServer
需要从 url 中删除前缀。下面的示例运行良好。
ui := http.FileServer(http.Dir("ui"))
myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
注意,上面的示例中没有 /ui/rest。您也可以将 http.FileServer
包装到 logger gorilla/handler 中,然后查看请求进入 FileServer 和响应 404 出去。
ui := handlers.CombinedLoggingHandler(os.Stderr,http.FileServer(http.Dir("ui"))
myRouter.Handle("/ui/", ui) // getting 404
// works with strip: myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui))
【讨论】:
router
的默认Handle
方法仍然像以前一样创建route
。我尝试了你上面所说的方法,"/ui/"
不会匹配所有带有"/ui/"
前缀的路径。 @dodgy_coder 的解决方案是正确的。使用默认的Handler
方法包含正则表达式或使用PathPrefix
以上是关于Golang Gorilla mux 与 http.FileServer 返回 404的主要内容,如果未能解决你的问题,请参考以下文章
GoLang/Mux 语法问题:if ID, Ok = mux.Vars(r)["ID"]; !行
GolangWeb 入门 08 集成 Gorilla Mux