シンプル 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 を開始します。ハンドルインデックス()。その後、通常どおり実行を続けます。
ハンドラー関数が応答ステータスを設定しない場合、または応答に何も書き込まない場合、Go は自動的にステータスを 200 (HTTP OK) に設定して戻ります。この動作は、コード内の匿名関数に適用されます。この関数は、応答ステータスを明示的に設定したり、go HandleIndex(w, r) 行の前に書き込みを行ったりしません。
HandleIndex() が別のメソッドで呼び出された場合goroutine では、匿名関数は実行を継続し、リクエストの処理で終了します。応答ステータスは事前に設定されていないため、Go は自動的に 200 HTTP OK に設定します。ただし、生成されたゴルーチンは、HandleIndex() 内で応答ステータスの設定も試行し、「複数の応答.WriteHeader 呼び出し」エラーが発生します。
Solution
Toこの問題を回避するには、最初の行から "go" キーワードを削除します。 goroutine:
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: multiple response.WriteHeader Calls」エラーが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。