亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Golang 中使用 http.FileServer 處理 GAE 上的 404 錯誤

如何在 Golang 中使用 http.FileServer 處理 GAE 上的 404 錯誤

Go
慕萊塢森 2022-03-07 22:34:13
我正在使用 Google App Engine 來服務我用 Hugo 生成的(半)靜態網站。我有一個“公共”目錄,所有的 HTML 文件都在其中存儲并提供。例如,我還有一些用于處理聯系表單的服務器端腳本。該app.yaml文件看起來像這樣。// app.yamlruntime: goapi_version: go1handlers:- url: /.*  script: _go_app  secure: always簡化的main.go文件看起來像這樣// main.gopackage mainimport (   "net/http"  "encoding/json"  "appengine"  "appengine/urlfetch"   )func init() {  fileHandler := http.FileServer(http.Dir("public"))  http.Handle("/", fileHandler)  http.HandleFunc("/contactus/", HandleContactus)}這工作得很好,并為 html 文件提供服務。但是,我正在尋找一種解決方案來處理找不到頁面并且響應404 Not Found為例如(或任何其他服務器錯誤)的情況。我的想法是創建一個自定義處理程序,它可以傳入http.Handle("/", myCustomHandler)并處理服務器響應,并404.html在必要時重定向到自定義等。我是 Go 新手,似乎無法弄清楚應該如何實現。我也看過 Gorilla Mux,但希望(如果可能的話)不使用外部庫來保持簡單?;谶@篇文章,我嘗試了以下package mainimport (   "net/http"  "encoding/json"  "appengine"  "appengine/urlfetch"   )func StaticSiteHandler(h http.Handler) http.Handler {  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){    h.ServeHTTP(w, r)  })}func init() {  fileHandler := http.FileServer(http.Dir("public"))  http.Handle("/", StaticSiteHandler(fileHandler))  http.HandleFunc("/contactus/", HandleContactus)}這個解決方案的工作原理是它也為我的 HTML 頁面提供服務,但是我仍然不知道如何處理服務器響應代碼。任何幫助將不勝感激。謝謝!
查看完整描述

2 回答

?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

為了使中間件與 . 解耦,http.FileServer在包裝它時,您可以傳遞一個特定的實現http.ResponseWriter

  1. 累積標頭,以防它們需要被丟棄(如果WriteHeader使用 404 調用)

  2. 如果WriteHeader使用 404 調用:

    1. 取消累積的標題

    2. 發送自定義 404

    3. 忽略Write來自包裝處理程序的調用

  3. 如果WriteHeader未調用,或使用非 404 調用,則:

    1. 將累積的標頭發送到真實的ResponseWriter

    2. WriteHeader將andWrite呼叫路由到真實的ResponseWriter

type notFoundInterceptorWriter struct {

    rw              http.ResponseWriter // set to nil to signal a 404 has been intercepted

    h               http.Header         // set to nil to signal headers have been emitted

    notFoundHandler http.Handler

    r               *http.Request

}


func (rw *notFoundInterceptorWriter) Header() http.Header {

    if rw.h == nil && rw.rw != nil {

        return rw.rw.Header()

    }

    return rw.h

}


func (rw *notFoundInterceptorWriter) WriteHeader(status int) {

    if status == http.StatusNotFound {

        rw.notFoundHandler.ServeHTTP(rw.rw, rw.r)

        rw.rw = nil

    } else {

        for k, vs := range rw.h {

            for _, v := range vs {

                rw.rw.Header().Add(k, v)

            }

        }

        rw.rw.WriteHeader(status)

    }

    rw.h = nil

}


func (rw *notFoundInterceptorWriter) Write(b []byte) (int, error) {

    if rw.rw != nil {

        return rw.rw.Write(b)

    }

    // ignore, so do as if everything was written OK

    return len(b), nil

}


func StaticSiteHandler(h, notFoundHandler http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        w = &notFoundInterceptorWriter{

            rw:              w,

            h:               make(http.Header),

            notFoundHandler: notFoundHandler,

            r:               r,

        }

        h.ServeHTTP(w, r)

    })

}


查看完整回答
反對 回復 2022-03-07
?
富國滬深

TA貢獻1790條經驗 獲得超9個贊

您可以在提供文件之前統計文件以查看它是否存在。根據需要調整 404 處理程序(發出模板等)


package main


import ( 

  "net/http"

  "path"

  "os"

)


func init() {

    http.Handle("/", staticHandler)

}


func error404Handler(w http.ResponseWriter, r *http.Request) {

    http.Error(w, "404 not found", http.StatusNotFound)

}


func staticHandler(w http.ResponseWriter, r *http.Request) {

    name := path.Clean(r.URL.Path)

    if _, err := os.Stat(name); err != nil {

        if os.IsNotExist(err) {

            error404Handler(w, r)

            return

        }


        http.Error(w, "internal error", http.StatusInternalServerError)

        return

    }


    return http.ServeFile(w, r, name)

}


查看完整回答
反對 回復 2022-03-07
  • 2 回答
  • 0 關注
  • 484 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號