预期的根文件和带有Golang Mux Router和http.FileServer的自定义404

时间:2018-09-20 12:35:55

标签: go routing http-status-code-404 mux

我正在Go中建立一个小型网站,而自定义404页面存在问题。这是我当前的路由器代码:

r := mux.NewRouter()

// Page routing
r.HandleFunc("/", homeHandler).Methods("GET")
r.HandleFunc("/example1", exampleOneHandler).Methods("GET")
r.HandleFunc("/example2", exampleTwoHandler).Methods("GET", "POST")

// Other paths for static assets omitted

// Psuedo-root directory for icon files, etc.
r.PathPrefix("/").Handler(http.FileServer(http.Dir("public")))

// 404 Page
r.NotFoundHandler = http.HandlerFunc(notFoundHandler)

log.Fatal(http.ListenAndServe(":1234", r))

因此,在第11行上没有PathPrefix定义的情况下,notFoundHandler会按预期命中,并返回自定义404 HTML。

但是,现在我添加了该路径定义,以适应根目录标准,例如favicon.ico,robots.txt,应用程序图标等,并且可以按预期工作。但是,副作用是,与/ example1或/ example2不匹配的所有内容(例如/ example3)都将通过http.FileServer在psuedo-root目录中查找名为“ example3”的文件。找不到文件后,FileServer会使用“ 404 not found”直接写入http.ResponseWriter,完全绕过mux的NotFoundHandler。

我看到的唯一可行的解​​决方案是为每个文件添加一条显式路由,但这似乎是一个非常残酷的解决方案。有没有更优雅的方式来解决我所缺少的这个问题?

1 个答案:

答案 0 :(得分:0)

为没有注册处理程序的路径激活notFoundHandler。并且由于您在路径"/"中注册了一个处理程序(文件服务器),因此该处理程序将始终匹配所有请求,因此不再调用未找到的处理程序。

要避免这种情况,最简单的方法是手动注册必须位于根目录的所有文件(这些文件不多,或者至少不应该存在)。如果您有一堆其他非标准静态文件,请将它们发布在/static/之类的路径下,这样未注册的路径,例如/example3会触发未找到的处理程序。

另一种解决方案是将文件服务器保留在路径"/"上,然后包装它,如果它返回状态404,请调用您自己的notFoundHandler来提供自定义错误页面。与我之前的建议相比,这要复杂得多,因此我仍然会继续这样做。