我有以下代码,一切正常.
var view404 = template.Must(template.ParseFiles("views/404.html"))
func NotFound(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
err := view404.Execute(w, nil)
check(err)
}
func main() {
router := mux.NewRouter()
router.StrictSlash(true)
router.NotFoundHandler = http.HandlerFunc(NotFound)
router.Handle("/", IndexHandler).Methods("GET")
router.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("public"))))
http.Handle("/", router)
http.ListenAndServe(":8000", nil)
}
Run Code Online (Sandbox Code Playgroud)
对路线的请求/cannot/find显示我的自定义404模板.我的/public/目录中的所有静态文件也正确提供.
我在处理不存在的静态文件并显示我的自定义NotFound处理程序时遇到问题.请求/public/cannot/find调用回复的标准http.NotFoundHandler
404页面不存在
如何为普通路由和静态文件使用相同的自定义NotFoundHandler?
更新
我最终FileHandler通过包装来实现我自己的http.ServeFile@Dewy Broto建议.
type FileHandler struct {
Path string
}
func (f FileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
prefix := "public"
http.ServeFile(w, r, path.Join(prefix, f.Path))
}
// ...
router.Handle("/css/styles.css", FileHandler{"/css/styles.css"}).Methods("GET")
Run Code Online (Sandbox Code Playgroud)
现在我的NotFound处理程序捕获所有丢失的路由,甚至丢失文件.
FileServer正在生成404响应.FileServer处理多路复用器传递给它的所有请求,包括丢失文件的请求.有几种方法可以使用自定义404页面提供静态文件:
这是第二种方法中描述的包装器的草图:
type hookedResponseWriter struct {
http.ResponseWriter
ignore bool
}
func (hrw *hookedResponseWriter) WriteHeader(status int) {
hrw.ResponseWriter.WriteHeader(status)
if status == 404 {
hrw.ignore = true
// Write custom error here to hrw.ResponseWriter
}
}
func (hrw *hookedResponseWriter) Write(p []byte) (int, error) {
if hrw.ignore {
return len(p), nil
}
return hrw.ResponseWriter.Write(p)
}
type NotFoundHook struct {
h http.Handler
}
func (nfh NotFoundHook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
nfh.h.ServeHTTP(&hookedResponseWriter{ResponseWriter: w}, r)
}
Run Code Online (Sandbox Code Playgroud)
通过包装FileServer来使用钩子:
router.PathPrefix("/public/").Handler(NotFoundHook{http.StripPrefix("/public/", http.FileServer(http.Dir("public")))})
Run Code Online (Sandbox Code Playgroud)
这个简单钩子的一个警告是它阻止了服务器中的优化,以便从文件复制到套接字.
| 归档时间: |
|
| 查看次数: |
4146 次 |
| 最近记录: |