2013-04-05 41 views
36

我嘗試使用Gorilla工具包的mux package在Go Web服務器中路由URL。使用this question爲指導,我有以下Go代碼:使用Gorilla工具包爲根URL提供靜態內容

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> 
... 

當我在我的網絡瀏覽器中訪問http://localhost:8100時,index.html內容已成功發送,但是,所有jscss網址返回404s。

我怎樣才能讓程序服務於static子目錄中的文件?

+0

你可能想看看這個討論(不使用大猩猩雖然)有關服務從根或子目錄靜態文件http://stackoverflow.com/questions/ 14086063 /服務主頁和靜態內容從根/ 14187941#14187941 – Deleplace 2013-04-05 15:27:45

+0

@Ripounet,我在我的研究過程中看到這個問題,但是,因爲它沒有使用大猩猩我從來沒有能夠得到的想法工作在我的設置中,我的目標之一是在根目錄下沒有任何靜態文件我的項目的宿主(main.go旁邊)。此外,它似乎非常類似於[@ Joe的回答](http://stackoverflow.com/a/15835001/971556),這也不適用於我的設置。 – jason 2013-04-05 17:12:35

回答

54

我想你可能會尋找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.Handle("/", r) 
    http.ListenAndServe(":8100", nil) 
} 
+0

這很有幫助,謝謝。我確實有一個問題試圖讓兩個別名工作。例如\t r.PathPrefix(「/ a /」)。Handler(http.FileServer(http.Dir(「b /」))) \t r.PathPrefix(「/」)。Handler(http.FileServer(http。 Dir(「c /」)))'在這種情況下,'c /'中的所有內容都被提供,但不是'b /'。嘗試了幾個不同的微妙變化,但沒有成功。有任何想法嗎? – markdsievers 2014-04-10 20:33:17

+1

@markdsievers,您可能需要從URL中去除「/ a /」部分。例如:'r.PathPrefix(「/ a /」)。Handler(http.StripPrefix(「/ a /」,http.FileServer(http.Dir(「b」))))'。 – Roman 2014-11-15 09:38:25

+1

是否可以添加NotFound處理程序? – 2015-06-20 16:01:22

4

試試這個:

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

這意味着將所有'src','href'等屬性改爲''/static/js/jquery.min.js''的形式。雖然技術上*會*工作。 – 2013-04-05 13:18:53

+0

這將允許加載JS和CSS文件,但'index.html'文件將不再在'http:// localhost:8100 /' – jason 2013-04-05 13:30:46

+0

上可用。我通常會將所有'images','css', '靜態'文件夾中的'js'等。 – Joe 2013-04-06 08:46:59

30

大量的試驗和錯誤之後,兩個以上的答案幫助我想出什麼爲我工作。我在web應用程序的根目錄中有靜態文件夾。

隨着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) 
} 

我希望它能幫助別人解決問題。

+10

這是唯一對我有用的答案。 – TheHippo 2015-09-24 16:42:55

+0

對於任何使用[golang workspace](https://golang.org/doc/code.html)的人來說:當你的工作目錄是[workspace]/src時,:= ...應該如下所示。 。's:= http.StripPrefix(「/ static /」,httpFileServer(http.Dir(「./web/ static /」)))' – Frito 2017-09-13 01:00:42

7

我在這裏有這個代碼,工作相當不錯,可重用。

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/") 
0

這將服務文件夾標誌內的所有文件,以及爲根目錄提供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)) 
}