在Go 的HTTP 伺服器中處理多個WriteHeader 呼叫
在Go 的net/http 套件中,必須避免給定的WriteHeader 進行多次呼叫要求。在主處理函數中進行 goroutine 呼叫可能會導致此問題,如下例所示:
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(r.URL) go HandleIndex(w, r) }) ... }
在匿名處理函數中,我們列印 URL 並啟動一個呼叫 HandleIndex 的 goroutine 。但是,這會導致控制台中出現「多次回應.WriteHeader 呼叫」錯誤。
為什麼會發生這種情況?預設情況下,如果未在處理函數中明確設置,Go 會將回應狀態設為 200(HTTP OK)。在此範例中,即使 HandleIndex 在單獨的 goroutine 中設定標頭,主處理程序函數也會完成,而不會向回應寫入任何內容或設定狀態。這會觸發Go自動設定狀態,導致多次寫入頭。
為了解決這個問題,我們可以從go HandleIndex中刪除go前綴,以便它與主處理函數在同一個goroutine中執行。或者,在 HandleIndex 中,我們可以在主處理函數返回之前設定回應標頭。
另一個選擇是使用中間件在請求到達主處理函數之前設定回應標頭。這樣,主處理函數就不需要設置header,並且中間件確保header 僅設置一次:
func main() { http.HandleFunc("/", middleware(HandleIndex)) ... } func middleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") next(w, r) } }
通過使用中間件,我們可以確保響應header在處理請求之前設置,避免多次WriteHeader 調用的任何潛在問題。
以上是為什麼在 Go 的 net/http 套件中使用帶有 WriteHeader 的 Goroutine 會導致「多次response.WriteHeader 調用」?的詳細內容。更多資訊請關注PHP中文網其他相關文章!