Go的Http句柄函数第一次为每个url调用两次

问题描述 投票:0回答:0

我有一个像下面这样的 Go HTTP 服务器:

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/GetAssign/", getAssign)

    http.ListenAndServe(":80", mux)
}

func getAssign(w http.ResponseWriter, r *http.Request) {
    log.Printf("Path: %v", r.URL.Path)
}

当我向我的服务器发送请求时,服务器第一次为每个 url 接收两次请求。例如,如果我调用

http://my-server/GetAssign/j34
,服务器会打印两次日志消息。如果我再次调用同一个 url,
http://my-server/GetAssign/j34
,日志消息只打印一次。如果我调用不同的 url,比如
http://my-server/GetAssign/hd4
,它会打印两次,因为这是 url 的第一次。

我预计该函数每次只调用一次。我怎样才能到达它?

编辑#1

我在我的代码中添加了一个

loggingHandler

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/GetAssign/", getAssign)

    http.ListenAndServe(":80", loggingHandler(mux))
}

func loggingHandler(handler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("Request: %s %s", r.Method, r.URL)
        recorder := httptest.NewRecorder()
        handler.ServeHTTP(recorder, r)
        for k, v := range recorder.Header() {
            w.Header()[k] = v
        }
        w.WriteHeader(recorder.Code)
        recorder.Body.WriteTo(w)
        if recorder.Code >= 300 && recorder.Code < 400 {
            log.Printf("Redirect: %d %s", recorder.Code, recorder.Header().Get("Location"))
        }
    })
}

func getAssign(w http.ResponseWriter, r *http.Request) {
    log.Printf("Path: %v", r.URL.Path)
}

当我向

http://my-server/GetAssign/j34
发送请求时,日志信息写了两次这样的:

2023/02/22 05:33:48 Request: GET /GetAssign/j34
2023/02/22 05:33:48 Path: /GetAssign/j34
2023/02/22 05:33:48 Request: GET /GetAssign/j34
2023/02/22 05:33:48 Path: /GetAssign/j34

编辑#2

我试过 chrome 浏览器和 Go code 作为客户端,但是这两个都和我说的一样的问题。

Chrome浏览器:我刚刚输入了url。

转码:

func main() {
    httpRequest, err := http.NewRequest("GET", fmt.Sprintf("%v/GetAssign/%v", endpoint, os.Args[1]), nil)
    if err != nil {
        log.Fatalf("Failed to make request, got %v", err)
    }

    client := NewHttpClient()
    response, err := client.Do(httpRequest)
    if err != nil {
        log.Fatalf("Failed to send request, got %v", err)
    }
    defer response.Body.Close()

    // this `log.Printf` is called once even though the server receives twice.
    log.Printf("Status Code: %v", response.StatusCode)
}
go go-http
© www.soinside.com 2019 - 2024. All rights reserved.