在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和其他按惯例或始终必须从根本上得到服务。
我要寻找的行为是在大多数Web服务器(例如Apache,Nginx或IIS)中发现的行为,它首先遍历您的规则,如果没有找到规则,它将查找实际文件,如果没有找到文件, 404 我的猜测是,不是编写a http.HandlerFunc,而是需要编写a http.Handler,它检查是否引用了具有扩展名的文件,如果是,则检查文件是否存在并提供文件,否则它是404s或提供主页,这是因为“ /”。不幸的是,我不确定如何开始这样的任务。
http.HandlerFunc
http.Handler
我的一部分说我正在使情况变得过于复杂,这使我觉得我缺少了什么?任何指导将不胜感激。
我想到的一件事可能对您有所帮助,您可以创建自己的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") } }