ホームページ >バックエンド開発 >Golang >Go の `net/http` パッケージの `WriteHeader` でゴルーチンを使用すると、なぜ「複数の応答.WriteHeader 呼び出し」が発生するのでしょうか?

Go の `net/http` パッケージの `WriteHeader` でゴルーチンを使用すると、なぜ「複数の応答.WriteHeader 呼び出し」が発生するのでしょうか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-28 19:02:11329ブラウズ

Why Does Using Goroutines with `WriteHeader` in Go's `net/http` Package Cause

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。