【Go】net/httpパッケージでhandlerが二回実行される


問題

Goのnet/httpパッケージを使ってhttpサーバを立てると、リクエストを処理する関数が二回実行される。(一回で良いのに)

具体的には、下記のようなコードを実行して、

main.go

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("handle")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe("127.0.0.1:8080", nil)
}

http://127.0.0.1:8080 にアクセスした後にページを更新すると、

handler関数が2回実行されている。なんでやねん。

原因

どうも、Chromeが

の両方にリクエストを送っているのが原因らしい。(https://github.com/golang/go/issues/1298

favicon.icoって何やねん

ホームページのシンボルアイコンとして使われる画像ファイルらしい。(https://wa3.i-3-i.info/word14168.html

解決策

favicon.icoへのリクエスト時は何もしないハンドラを登録する。

main.go
package main

import (
    "fmt"
    "net/http"
)

// 本命のハンドラ
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("handle")
}

// 何もしないハンドラ
func handlerICon(w http.ResponseWriter, r *http.Request) {}

func main() {
    // 本命のハンドラを登録
    http.HandleFunc("/", handler)

    // 何もしないハンドラを登録
    http.HandleFunc("/favicon.ico", handlerICon)

    http.ListenAndServe("127.0.0.1:8080", nil)
}

あとがき

軽くハマったが英語でググったらすぐ解決した。英語で調べるのだいじ。