2013-04-05 5 views
36

Ich versuche, das Gorilla-Toolkit mux package zu verwenden, um URLs auf einem Go-Webserver zu routen. Mit this question als Leitfaden ich folgende Go-Code haben:Bereitstellung von statischem Inhalt mit einer Stamm-URL mit dem Gorilla-Toolkit

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

Die Verzeichnisstruktur ist:

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

Die Javascript und CSS-Dateien werden in index.html wie folgt verwiesen:

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

Als ich http://localhost:8100 in meinem Web-Browser Zugriff auf den index.html Inhalt erfolgreich geliefert, aber alle die js und css URLs geben 404s zurück.

Wie bekomme ich das Programm, um Dateien aus static Unterverzeichnissen zu liefern?

+0

Man könnte diese Diskussion sehen wollen (allerdings nicht mit Gorilla) über dienen statische Dateien von der Wurzel oder Unterverzeichnisse http://stackoverflow.com/questions/ 14086063/Serve-Homepage-und-static-content-von-root/14187941 # 14187941 – Deleplace

+0

@Ripounet, ich diese Frage bei meinen Recherchen sah jedoch, da es nicht mit Gorilla war ich nie in der Lage war, die Ideen an der Arbeit mit meinem Setup, wo eines meiner Ziele war, keine statischen Dateien in der Wurzel di zu haben Pfarrhaus meines Projektes (neben 'main.go'). Es scheint auch sehr ähnlich zu [@ Joes Antwort] (http://stackoverflow.com/a/15835001/971556) unten, die auch nicht mit meinem Setup funktioniert. – jason

Antwort

54

Ich glaube, Sie könnten für PathPrefix suchen ...

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

Das war hilfreich, danke. Ich hatte ein Problem beim Versuch, zwei Aliase zu bekommen. zB \t 'r.PathPrefix ("/a/"). Handler (http.FileServer (http.Dir (" b/"))) \t r.PathPrefix ("/"). Handler (http.FileServer (http. Dir ("c /"))) 'In diesem Fall wird alles in' c/'serviert, aber nicht' b/'. Versuchte ein paar verschiedene subtile Variationen, aber ohne Erfolg. Irgendwelche Ideen? – markdsievers

+1

@markdsievers, müssen Sie möglicherweise "/ a /" Teil von der URL entfernen. Beispiel: 'r.PathPrefix ("/a/"). Handler (http.StripPrefix ("/a/", http.FileServer (http.Dir (" b ")))). – Roman

+1

Ist es möglich, einen NotFound-Handler hinzuzufügen? –

4

Versuchen Sie folgendes:

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

Das würde bedeuten, alle Attribute "src", "href" usw. in das Formular "/static/js/jquery.min.js" 'zu ändern. Obwohl technisch * würde * funktionieren. –

+0

, die die JS und CSS-Dateien können geladen werden, aber die 'index.html' Datei nicht mehr auf' http zur Verfügung stehen würde: // localhost: 8100/' – jason

+0

ich in der Regel alle' images' setzen, 'css', 'js' etc. im' statischen' Ordner. – Joe

30

Nach viel Versuch und Irrtum, beide oben genannten Antworten half mir in den kommenden up mit dem, was hat für mich gearbeitet. Ich habe einen statischen Ordner im Stammverzeichnis der Web-App.

Zusammen mit PathPrefix musste ich StripPrefix für die Route zu rekursiv arbeiten verwenden.

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

Ich hoffe, es hilft jemand anderen Probleme haben.

+10

Das ist die einzige Antwort, die für mich funktioniert hat. – TheHippo

+0

Für alle, die den [golang workspace] (https://golang.org/doc/code.html) verwenden, sollte 's: = ...' wie folgt lauten, wenn Ihr Arbeitsverzeichnis '[workspace]/src' ist. . 's: = http.StripPrefix ("/static/", httpFileServer (http.Dir (" ./ web/static/"))) – Frito

7

Ich habe diesen Code hier, die sehr schön und ist wiederverwendbar funktioniert.

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

Dies dient alle Dateien innerhalb der Ordner-Flag sowie serving Index.html im Stammverzeichnis.

Nutzungs

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

-Code

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