2014-01-20 67 views
20

我看到的問題是,我試圖使用http.FileServer Gorilla mux Router.Handle函數。Golang Gorilla多路複用器與http.FileServer返回404

這不起作用(圖像返回404)..

myRouter := mux.NewRouter() 
myRouter.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/")))) 

這個工程(圖像顯示OK)..下面

http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/")))) 

簡約歸Web服務器程序,顯示問題...

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" height="640" width="480"> 
    </p> 
    </body> 
</html> 
` 

回答

43

我張貼這在golang堅果討論小組,得到了this solution from Toni Cárdenas ...

標準net/http ServeMux(這是您在使用http.Handle時使用的標準處理程序)和多路複用路由器有不同的地址匹配方式。

查看http://golang.org/pkg/net/http/#ServeMuxhttp://godoc.org/github.com/gorilla/mux之間的差異。

所以基本上,http.Handle('/images/', ...)匹配「/圖片/什麼」,而myRouter.Handle('/images/', ...)只有匹配「/圖片/」,如果你想處理「/圖片/什麼」,你必須......

  1. 設置正則表達式匹配你的路由器或
  2. 使用PathPrefix方法你的路由器上,如:

代碼示例

1.

myRouter.Handle('/images/{rest}', 
    http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))) 
) 

2.

myRouter.PathPrefix("/images/").Handler(
    http.StripPrefix("/images/", http.FileServer(http.Dir(HomeFolder + "images/"))) 
) 
+3

+1#2在我當前的項目中取得了成功(在我偶然發現這個答案之前,讓讀者確信#2是我正在使用和工作的)。 – eduncan911

+2

+1 - #2也適用於我 – Aaron

+0

只需添加註釋,請記住,如果您是像我這樣的golang新手,golang不會喜歡#2格式的語句。在golang停止抱怨期待逗號之前,我需要將所有三行代碼合併成一行(語法沒有變化,只是改變空格)。 #2是正確的答案,它只是以這種方式形成的,這會給像我這樣的新手和新手帶來問題。 –

1

隨着2015年5月的gorilla/mux包仍然沒有版本發行。但現在問題不同了。這不是myRouter.Handle不匹配的網址,需要正則表達式,它!但是http.FileServer需要將前綴從url中刪除。下面的例子工作正常。

ui := http.FileServer(http.Dir("ui")) 
myRouter.Handle("/ui/", http.StripPrefix("/ui/", ui)) 

注意,存在abowe例如無/ UI/{休息}。您也可以將http.FileServer包裝到記錄器大猩猩/處理程序中,並查看請求來到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)) 
+0

'router'的默認'Handle'方法仍然像以前一樣創建一個'route'。我嘗試了上面所述的方法,'/ ui /「'不能匹配所有帶有」/ ui /「前綴的路徑。 @ dodgy_coder的解決方案是正確的。要麼使用默認的'Handler'方法包含正則表達式,要麼使用'PathPrefix' – thecalvinchan