在Golang,我怎么在服务的同时仍然有服务于主页的根目录处理静态内容进行根目录。
使用下面的简单的Web服务器为例:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", HomeHandler) // homepage
http.ListenAndServe(":8080", nil)
}
func HomeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "HomeHandler")
}
如果我做
http.Handle("/", http.FileServer(http.Dir("./")))
我收到了恐慌说,我有两个登记为“/”。 每Golang例子中,我发现在互联网上建议正在服刑的静态内容进行不同的目录中,但没有太大的帮助像sitemap.xml的,为favicon.ico,的robots.txt和其它文件的事情是通过实践或授权总是送达了根。
我所寻求的行为是在大多数网络服务器如Apache,Nginx的,或IIS,在第一次穿越你的规则中找到的行为,如果没有规则,发现它查找实际的文件,如果没有文件找到404。 我的猜测是不是写一个http.HandlerFunc
,我需要写一个http.Handler
用来检查是否我引用带有扩展名的文件,如果是检查文件的存在,并提供文件,否则404或服务于主页是请求是“/”。 不幸的是我不能确定如何甚至开始这样的任务。
我的一部分说我是大规模过于复杂这让我觉得我失去了一些东西的情况? 任何指导将不胜感激。
有一件事我想过可能会帮助你的是,你可以创建自己的ServeMux。 我添加到您的例子,这样chttp是,你可以有一个ServeMux提供静态文件。 该HomeHandler然后检查,看它是否应该成为一个文件或没有。 我只是检查了“” 但是你可以做很多事情。 只是一个想法,可能不是你所期待的。
package main
import (
"fmt"
"net/http"
"strings"
)
var chttp = http.NewServeMux()
func main() {
chttp.Handle("/", http.FileServer(http.Dir("./")))
http.HandleFunc("/", HomeHandler) // homepage
http.ListenAndServe(":8080", nil)
}
func HomeHandler(w http.ResponseWriter, r *http.Request) {
if (strings.Contains(r.URL.Path, ".")) {
chttp.ServeHTTP(w, r)
} else {
fmt.Fprintf(w, "HomeHandler")
}
}
一种替代(不使用ServeMux )的解决方案是显式服务位于根目录中的每个文件。 背后的想法是保持的基于root用户的文件的数量非常少。 sitemap.xml的 , favicon.ico的 , robots.txt的确实规定须送达根:
package main
import (
"fmt"
"net/http"
)
func HomeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "HomeHandler")
}
func serveSingle(pattern string, filename string) {
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, filename)
})
}
func main() {
http.HandleFunc("/", HomeHandler) // homepage
// Mandatory root-based resources
serveSingle("/sitemap.xml", "./sitemap.xml")
serveSingle("/favicon.ico", "./favicon.ico")
serveSingle("/robots.txt", "./robots.txt")
// Normal resources
http.Handle("/static", http.FileServer(http.Dir("./static/")))
http.ListenAndServe(":8080", nil)
}
请将所有其他资源(CSS,JS等)以适当的子目录,如/static/
。
使用大猩猩MUX包 :
r := mux.NewRouter()
//put your regular handlers here
//then comes root handler
r.HandleFunc("/", homePageHandler)
//if a path not found until now, e.g. "/image/tiny.png"
//this will look at "./public/image/tiny.png" at filesystem
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./public/")))
http.Handle("/", r)
http.ListenAndServe(":8080", nil)