使用Gorilla工具包以根URL提供静态内容。

huangapple go评论80阅读模式
英文:

Serving static content with a root URL with the Gorilla toolkit

问题

我正在尝试使用Gorilla工具包的mux包来路由Go web服务器中的URL。根据这个问题作为指南,我有以下Go代码:

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>

index.html中引用了JavaScript和CSS文件,如下所示:

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

当我在Web浏览器中访问http://localhost:8100时,成功传送了index.html的内容,但是所有的jscss URL都返回404错误。

我该如何让程序能够提供static子目录中的文件?

英文:

I am attempting to use the Gorilla toolkit's mux package to route URLs in a Go web server. Using this question as a guide I have the following Go code:

func main() {
	r := mux.NewRouter()
	r.Handle(&quot;/&quot;, http.FileServer(http.Dir(&quot;./static/&quot;)))
	r.HandleFunc(&quot;/search/{searchTerm}&quot;, Search)
	r.HandleFunc(&quot;/load/{dataId}&quot;, Load)
	http.Handle(&quot;/&quot;, r)
	http.ListenAndServe(&quot;:8100&quot;, nil)
}

The directory structure is:

...
main.go
static\
  | index.html
  | js\
     | &lt;js files&gt;
  | css\
     | &lt;css files&gt;

The Javascript and CSS files are referenced in index.html like this:

...
&lt;link rel=&quot;stylesheet&quot; href=&quot;css/redmond/jquery-ui.min.css&quot;/&gt;
&lt;script src=&quot;js/jquery.min.js&quot;&gt;&lt;/script&gt;
...

When I access http://localhost:8100 in my web browser the index.html content is delivered successfully, however, all the js and css URLs return 404s.

How can I get the program to serve files out of static sub-directories?

答案1

得分: 107

我认为你可能在寻找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.ListenAndServe(":8100", r)
}
英文:

I think you might be looking for PathPrefix...

func main() {
    r := mux.NewRouter()
    r.HandleFunc(&quot;/search/{searchTerm}&quot;, Search)
    r.HandleFunc(&quot;/load/{dataId}&quot;, Load)
    r.PathPrefix(&quot;/&quot;).Handler(http.FileServer(http.Dir(&quot;./static/&quot;)))
    http.ListenAndServe(&quot;:8100&quot;, r)
}

答案2

得分: 53

After a lot of trial and error, both above answers helped me in coming up with what worked for me. I have static folder in web app's root directory.

Along with PathPrefix I had to use StripPrefix for getting route to work recursively.

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

I hope it helps somebody else having problems.

英文:

After a lot of trial and error, both above answers helped me in coming up with what worked for me. I have static folder in web app's root directory.

Along with PathPrefix I had to use StripPrefix for getting route to work recursively.

package main

import (
	&quot;log&quot;
	&quot;net/http&quot;
    &quot;github.com/gorilla/mux&quot;
)

func main() {
	r := mux.NewRouter()
	s := http.StripPrefix(&quot;/static/&quot;, http.FileServer(http.Dir(&quot;./static/&quot;)))
	r.PathPrefix(&quot;/static/&quot;).Handler(s)
	http.Handle(&quot;/&quot;, r)
	err := http.ListenAndServe(&quot;:8081&quot;, nil)
}

I hope it helps somebody else having problems.

答案3

得分: 10

我有这段代码,它运行得很好,而且可以重复使用。

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/")
英文:

I have this code here that works quite nice and is re-usable.

func ServeStatic(router *mux.Router, staticDirectory string) {
    staticPaths := map[string]string{
        &quot;styles&quot;:           staticDirectory + &quot;/styles/&quot;,
        &quot;bower_components&quot;: staticDirectory + &quot;/bower_components/&quot;,
        &quot;images&quot;:           staticDirectory + &quot;/images/&quot;,
        &quot;scripts&quot;:          staticDirectory + &quot;/scripts/&quot;,
    }
    for pathName, pathValue := range staticPaths {
        pathPrefix := &quot;/&quot; + pathName + &quot;/&quot;
        router.PathPrefix(pathPrefix).Handler(http.StripPrefix(pathPrefix,
            http.FileServer(http.Dir(pathValue))))
    }
}
router := mux.NewRouter()
ServeStatic(router, &quot;/static/&quot;)

答案4

得分: 5

尝试这样做:

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

Try this:

fileHandler := http.StripPrefix(&quot;/static/&quot;, http.FileServer(http.Dir(&quot;/absolute/path/static&quot;)))
http.Handle(&quot;/static/&quot;, fileHandler)

答案5

得分: 0

这个代码会将文件夹flag中的所有文件都提供服务,并在根目录下提供index.html的服务。

#用法
//端口默认值为8500
//文件夹默认为当前目录
go run main.go

   //在你的情况下,不要忘记最后的斜杠
   go run main.go -folder static/

   //不要这样
   go run main.go -folder ./

#代码

    package main

import (
	&quot;flag&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;os&quot;
	&quot;strconv&quot;
	&quot;strings&quot;

	&quot;github.com/gorilla/handlers&quot;
	&quot;github.com/gorilla/mux&quot;
	&quot;github.com/kr/fs&quot;
)

func main() {
	mux := mux.NewRouter()

	var port int
	var folder string
	flag.IntVar(&amp;port, &quot;port&quot;, 8500, &quot;端口的帮助信息&quot;)
	flag.StringVar(&amp;folder, &quot;folder&quot;, &quot;&quot;, &quot;文件夹的帮助信息&quot;)

	flag.Parse()

	walker := fs.Walk(&quot;./&quot; + folder)
	for walker.Step() {
		var www string

		if err := walker.Err(); err != nil {
			fmt.Fprintln(os.Stderr, &quot;错误&quot;)
			continue
		}
		www = walker.Path()
		if info, err := os.Stat(www); err == nil &amp;&amp; !info.IsDir() {
			mux.HandleFunc(&quot;/&quot;+strings.Replace(www, folder, &quot;&quot;, -1), func(w http.ResponseWriter, r *http.Request) {
				http.ServeFile(w, r, www)
			})
		}
	}
	mux.HandleFunc(&quot;/&quot;, func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, folder+&quot;index.html&quot;)
	})
	http.ListenAndServe(&quot;:&quot;+strconv.Itoa(port), handlers.LoggingHandler(os.Stdout, mux))
}
英文:

This serve all files inside the folder flag, as well as serving index.html at the root.

#Usage
//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 (
	&quot;flag&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;os&quot;
	&quot;strconv&quot;
	&quot;strings&quot;

	&quot;github.com/gorilla/handlers&quot;
	&quot;github.com/gorilla/mux&quot;
	&quot;github.com/kr/fs&quot;
)

func main() {
	mux := mux.NewRouter()

	var port int
	var folder string
	flag.IntVar(&amp;port, &quot;port&quot;, 8500, &quot;help message for port&quot;)
	flag.StringVar(&amp;folder, &quot;folder&quot;, &quot;&quot;, &quot;help message for folder&quot;)

	flag.Parse()

	walker := fs.Walk(&quot;./&quot; + folder)
	for walker.Step() {
		var www string

		if err := walker.Err(); err != nil {
			fmt.Fprintln(os.Stderr, &quot;eroooooo&quot;)
			continue
		}
		www = walker.Path()
		if info, err := os.Stat(www); err == nil &amp;&amp; !info.IsDir() {
			mux.HandleFunc(&quot;/&quot;+strings.Replace(www, folder, &quot;&quot;, -1), func(w http.ResponseWriter, r *http.Request) {
				http.ServeFile(w, r, www)
			})
		}
	}
	mux.HandleFunc(&quot;/&quot;, func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, folder+&quot;index.html&quot;)
	})
	http.ListenAndServe(&quot;:&quot;+strconv.Itoa(port), handlers.LoggingHandler(os.Stdout, mux))
}

huangapple
  • 本文由 发表于 2013年4月5日 20:41:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/15834278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定