표준 http 패키지로 사용자 지정 404 오류 페이지 표시
우리가 가지고 있다고 가정하면 :
http.HandleFunc("/smth", smthPage)
http.HandleFunc("/", homePage)
사용자가 잘못된 URL을 입력하면 일반 "404 페이지를 찾을 수 없음"이 표시됩니다. 해당 사례에 대한 사용자 지정 페이지를 반환하려면 어떻게합니까?
Gorilla / Mux 관련 업데이트
순수한 net / http 패키지를 사용하는 사람들에게 허용되는 대답은 괜찮습니다.
gorilla / mux를 사용하는 경우 다음과 같이 사용해야합니다.
func main() {
r := mux.NewRouter()
r.NotFoundHandler = http.HandlerFunc(notFound)
}
그리고 func notFound(w http.ResponseWriter, r *http.Request)
원하는대로 구현하십시오 .
나는 보통 이것을한다 :
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", homeHandler)
http.HandleFunc("/smth/", smthHandler)
http.ListenAndServe(":12345", nil)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
errorHandler(w, r, http.StatusNotFound)
return
}
fmt.Fprint(w, "welcome home")
}
func smthHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/smth/" {
errorHandler(w, r, http.StatusNotFound)
return
}
fmt.Fprint(w, "welcome smth")
}
func errorHandler(w http.ResponseWriter, r *http.Request, status int) {
w.WriteHeader(status)
if status == http.StatusNotFound {
fmt.Fprint(w, "custom 404")
}
}
여기에서는 사용자 지정 404 만 표시하도록 코드를 단순화했지만 실제로는이 설정으로 더 많은 작업을 수행합니다.를 사용하여 모든 HTTP 오류를 처리합니다. errorHandler
여기서 유용한 정보를 기록하고 자신에게 이메일을 보냅니다.
다음은 내가 선택한 접근 방식입니다. 브라우저 북마크를 잃어 버렸기 때문에인지 할 수없는 코드 스 니펫을 기반으로합니다.
샘플 코드 : (내 메인 패키지에 넣었습니다)
type hijack404 struct {
http.ResponseWriter
R *http.Request
Handle404 func (w http.ResponseWriter, r *http.Request) bool
}
func (h *hijack404) WriteHeader(code int) {
if 404 == code && h.Handle404(h.ResponseWriter, h.R) {
panic(h)
}
h.ResponseWriter.WriteHeader(code)
}
func Handle404(handler http.Handler, handle404 func (w http.ResponseWriter, r *http.Request) bool) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
hijack := &hijack404{ ResponseWriter:w, R: r, Handle404: handle404 }
defer func() {
if p:=recover(); p!=nil {
if p==hijack {
return
}
panic(p)
}
}()
handler.ServeHTTP(hijack, r)
})
}
func fire404(res http.ResponseWriter, req *http.Request) bool{
fmt.Fprintf(res, "File not found. Please check to see if your URL is correct.");
return true;
}
func main(){
handler_statics := http.StripPrefix("/static/", http.FileServer(http.Dir("/Path_To_My_Static_Files")));
var v_blessed_handler_statics http.Handler = Handle404(handler_statics, fire404);
http.Handle("/static/", v_blessed_handler_statics);
// add other handlers using http.Handle() as necessary
if err := http.ListenAndServe(":8080", nil); err != nil{
log.Fatal("ListenAndServe: ", err);
}
}
func fire404
오류 404에 대한 메시지의 고유 한 버전을 출력 하도록 을 사용자 정의하십시오 .
Gorilla Mux를 사용하는 경우 주요 기능을 다음과 같이 교체 할 수 있습니다.
func main(){
handler_statics := http.StripPrefix("/static/", http.FileServer(http.Dir("/Path_To_My_Static_Files")));
var v_blessed_handler_statics http.Handler = Handle404(handler_statics, fire404);
r := mux.NewRouter();
r.PathPrefix("/static/").Handler(v_blessed_handler_statics);
// add other handlers with r.HandleFunc() if necessary...
http.Handle("/", r);
log.Fatal(http.ListenAndServe(":8080", nil));
}
나는 단지 Go를 처음 사용하기 때문에 코드가 틀리면 친절하게 수정하십시오. 감사.
자신 만의 notFound 핸들러를 만들고 처리하지 않는 경로에 대해 HandleFunc에 등록하기 만하면됩니다.
라우팅 논리를 최대한 제어하려면 사용자 지정 서버와 사용자 지정 처리기 유형을 사용해야합니다.
이를 통해 HandleFunc가 허용하는 것보다 더 복잡한 라우팅 로직을 구현할 수 있습니다.
고대의 실이지만, 방금 차단할 무언가를 만들었습니다 http.ResponseWriter
. 여기에 관련이있을 수 있습니다.
package main
//GAE POC originally inspired by https://thornelabs.net/2017/03/08/use-google-app-engine-and-golang-to-host-a-static-website-with-same-domain-redirects.html
import (
"net/http"
)
func init() {
http.HandleFunc("/", handler)
}
// HeaderWriter is a wrapper around http.ResponseWriter which manipulates headers/content based on upstream response
type HeaderWriter struct {
original http.ResponseWriter
done bool
}
func (hw *HeaderWriter) Header() http.Header {
return hw.original.Header()
}
func (hw *HeaderWriter) Write(b []byte) (int, error) {
if hw.done {
//Silently let caller think they are succeeding in sending their boring 404...
return len(b), nil
}
return hw.original.Write(b)
}
func (hw *HeaderWriter) WriteHeader(s int) {
if hw.done {
//Hmm... I don't think this is needed...
return
}
if s < 400 {
//Set CC header when status is < 400...
//TODO: Use diff header if static extensions
hw.original.Header().Set("Cache-Control", "max-age=60, s-maxage=2592000, public")
}
hw.original.WriteHeader(s)
if s == 404 {
hw.done = true
hw.original.Write([]byte("This be custom 404..."))
}
}
func handler(w http.ResponseWriter, r *http.Request) {
urls := map[string]string{
"/example-post-1.html": "https://example.com/post/example-post-1.html",
"/example-post-2.html": "https://example.com/post/example-post-2.html",
"/example-post-3.html": "https://example.com/post/example-post-3.html",
}
w.Header().Set("Strict-Transport-Security", "max-age=15768000")
//TODO: Put own logic
if value, ok := urls[r.URL.Path]; ok {
http.Redirect(&HeaderWriter{original: w}, r, value, 301)
} else {
http.ServeFile(&HeaderWriter{original: w}, r, "static/"+r.URL.Path)
}
}
Maybe I'm wrong, but I just checked the sources: http://golang.org/src/pkg/net/http/server.go
It seems like specifying custom NotFound() function is hardly possible: NotFoundHandler() returns a hardcoded function called NotFound().
Probably, you should submit an issue on this.
As a workaround, you can use your "/" handler, which is a fallback if no other handlers were found (as it is the shortest one). So, check is page exists in that handler and return a custom 404 error.
you can define
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
if request.URL.Path != "/" {
writer.WriteHeader(404)
writer.Write([]byte(`not found, da xiong dei !!!`))
return
}
})
when access not found resource, it will execute to http.HandleFunc("/", xxx)
참고URL : https://stackoverflow.com/questions/9996767/showing-custom-404-error-page-with-standard-http-package
'Program Tip' 카테고리의 다른 글
Windows의 내장 ZIP 압축을 스크립팅 할 수 있습니까? (0) | 2020.12.05 |
---|---|
Spring 구성 디버깅 (0) | 2020.12.05 |
지역 가치와 마스터 가치의 차이점은 무엇입니까 (0) | 2020.12.05 |
browserify / requirejs 모듈과 ES6 모듈의 차이점은 무엇입니까? (0) | 2020.12.05 |
clang의 stdbool.h에 #define false false가 포함 된 이유 (0) | 2020.12.05 |