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 を開始します。 。ただし、これにより、コンソールに「multiple response.WriteHeader Calls」というエラーが発生します。
なぜこれが起こるのでしょうか?ハンドラー関数で明示的に設定されていない場合、Go はデフォルトで応答ステータスを 200 (HTTP OK) に設定します。この例では、HandleIndex が別の goroutine でヘッダーを設定しても、メインのハンドラー関数は応答に何も書き込んだりステータスを設定したりすることなく完了します。これにより、Go が自動的にステータスを設定するようにトリガーされ、複数のヘッダーの書き込みが行われます。
この問題を解決するには、go HandleIndex から go プレフィックスを削除して、メイン ハンドラー関数と同じ goroutine で実行されるようにします。あるいは、HandleIndex では、メイン ハンドラー関数が戻る前に応答ヘッダーを設定できます。
別のオプションは、リクエストがメイン ハンドラー関数に到達する前に、ミドルウェアを使用して応答ヘッダーを設定することです。このように、メイン ハンドラー関数はヘッダーを設定する必要がなく、ミドルウェアはヘッダーが 1 回だけ設定されることを保証します。
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) } }
ミドルウェアを使用することで、応答ヘッダーがリクエストを処理する前に設定して、複数の WriteHeader 呼び出しによる潜在的な問題を回避します。
以上がGo の `net/http` パッケージの `WriteHeader` でゴルーチンを使用すると、なぜ「複数の応答.WriteHeader 呼び出し」が発生するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。