簡單 HTTP 伺服器中的多個 WriteHeader 呼叫
使用 net/http 套件在 Go 中實作的基本 HTTP伺服器表現出異常行為,如錯誤訊息指示:
http: multiple response.WriteHeader calls
此錯誤表示伺服器正在嘗試將回應標頭寫入多個次,這是 HTTP 規範不允許的。讓我們分析程式碼以了解出現此問題的原因:
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(r.URL) go HandleIndex(w, r) }) fmt.Println("Starting Server...") log.Fatal(http.ListenAndServe(":5678", nil)) } func HandleIndex(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Write([]byte("Hello, World!")) }
分析
主要問題在於註冊為傳入請求處理程序的匿名函數:
func(w http.ResponseWriter, r *http.Request) { fmt.Println(r.URL) go HandleIndex(w, r) }
函數列印請求URL 並啟動一個新的goroutine 來呼叫HandleIndex()。然後,它繼續正常執行。
如果處理函數沒有設定回應狀態或寫入任何內容,Go 會自動將狀態設為 200(HTTP OK)並傳回。此行為適用於我們程式碼中的匿名函數,該函數不會明確設定回應狀態或在 go HandleIndex(w, r) 行之前寫入回應狀態。
當在單獨的程式碼中呼叫 HandleIndex() 時goroutine 中,匿名函數繼續執行,以請求處理結束。由於事先沒有設定回應狀態,Go 會自動設定為 200 HTTP OK。然而,產生的 goroutine 也會嘗試在 HandleIndex() 中設定回應狀態,導致「多次 response.WriteHeader 呼叫」錯誤。
解決方案func(w http.ResponseWriter, r *http.Request) { fmt.Println(r.URL) HandleIndex(w, r) }
func(w http.ResponseWriter, r *http.Request) { fmt.Println(r.URL) w.Write([]byte("Hello, World!")) go HandleIndex(w, r) }
以上是為什麼我的 Go HTTP 伺服器中會出現「http:多重回應.WriteHeader 呼叫」錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!