2013-04-05 10 views
36

Sto tentando di utilizzare il toolkit Gorilla mux package per indirizzare gli URL in un server Web Go. Utilizzando this question come guida ho il seguente codice Go:Elaborazione di contenuto statico con un URL radice con il toolkit Gorilla

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

La struttura di directory è:

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

Il Javascript e file CSS si fa riferimento in index.html come questo:

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

Quando accedo allo http://localhost:8100 nel browser Web, il contenuto dello index.html viene consegnato correttamente, tuttavia, tutti gliGli URLe css restituiscono 404 secondi.

Come è possibile ottenere il programma per servire i file delle sottodirectory static?

+0

Si potrebbe desiderare di vedere questo discussione (se non utilizzano Gorilla però) di servire i file statici da root o sottodirectory http://stackoverflow.com/questions/ 14086063/serve-homepage-e-static-content-from-root/14187941 # 14187941 – Deleplace

+0

@Ripounet, ho visto quella domanda durante la mia ricerca, tuttavia, poiché non stava usando Gorilla, non ero mai riuscito a far funzionare le idee con il mio setup in cui uno dei miei obiettivi era di non avere file statici nella root di canonica del mio progetto (accanto a 'main.go'). Inoltre, sembra molto simile a [@ Joe's answer] (http://stackoverflow.com/a/15835001/971556) qui sotto, che inoltre non funzionerà con il mio setup. – jason

risposta

54

Penso che potrebbe essere alla ricerca di 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

Questo è stato utile, grazie. Ho avuto un problema nel tentativo di far funzionare due alias. es. \t 'r.PathPrefix ("/a/"). Handler (http.FileServer (http.Dir (" b/"))) \t r.PathPrefix ("/"). Handler (http.FileServer (http. Dir ("c /"))) 'In questo caso, tutto in' c/'è servito, ma non' b/'. Ho provato alcune varianti sottili ma senza successo. Qualche idea? – markdsievers

+1

@markdsievers, potrebbe essere necessario rimuovere la parte "/ a /" dall'URL. Esempio: 'r.PathPrefix ("/a/"). Handler (http.StripPrefix ("/a/", http.FileServer (http.Dir (" b "))))'. – Roman

+1

È possibile aggiungere un gestore NotFound? –

4

Prova questo:

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

Significa cambiare tutti gli attributi 'src',' href' etc nella forma '" /static/js/jquery.min.js "'. Anche se tecnicamente * funzionerebbe *. –

+0

Quale permetterà il caricamento dei file JS e CSS, ma il file 'index.html' non sarebbe più disponibile su' http: // localhost: 8100/' – jason

+0

Di solito metto tutte le' immagini', 'css', 'js' etc nella cartella' static'. – Joe

30

Dopo un sacco di tentativi ed errori, entrambe le risposte di cui sopra mi ha aiutato a venire con quello che ha funzionato per me Ho una cartella statica nella directory principale dell'app web.

Insieme a PathPrefix ho dovuto utilizzare StripPrefix per ottenere il percorso di lavoro in modo ricorsivo.

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

Spero che aiuti qualcun altro a riscontrare problemi.

+10

Questa è l'unica risposta che ha funzionato per me. – TheHippo

+0

Per chiunque usi lo spazio di lavoro [golang] (https://golang.org/doc/code.html) 's: = ...' dovrebbe leggere come segue quando la directory di lavoro è '[workspace]/src' .. . 's: = http.StripPrefix ("/static/", httpFileServer (http.Dir (" ./ web/static/")))' – Frito

7

Ho qui questo codice che funziona abbastanza bene ed è riutilizzabile.

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

Questo serve tutti i file all'interno del flag di cartella, oltre a servire index.html nella radice.

Uso

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

Codice

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