gpt4 book ai didi

http - 多个 response.WriteHeader 在非常简单的示例中调用?

转载 作者:IT老高 更新时间:2023-10-28 13:00:59 26 4
gpt4 key购买 nike

我有一个最基本的 net/http 程序,用来学习 Go 中的命名空间:

package main

import (
"fmt"
"log"
"net/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!"))
}

当我在 Chrome 中运行程序并连接到 localhost:5678 时,我在控制台中得到了这个:

Starting Server...
/
2015/01/15 13:41:29 http: multiple response.WriteHeader calls
/favicon.ico
2015/01/15 13:41:29 http: multiple response.WriteHeader calls

但我不明白这怎么可能。我打印 URL,启动一个新的 goroutine,编写一次 header ,然后给它一个静态的 Hello, World! 正文,似乎正在发生两件事之一。要么是幕后的东西正在编写另一个 header ,要么以某种方式 HandleIndex 为同一个请求调用了两次。我该怎么做才能停止编写多个标题?

编辑:这似乎与 go HandleIndex(w, r) 行有关,因为如果我删除 go 并使其成为函数调用而不是一个goroutine,我没有遇到任何问题,浏览器会获取它的数据。由于它是一个 goroutine,我得到了多个 WriteHeader 错误,并且浏览器没有显示“Hello World”。为什么要让这个 goroutine 破坏它?

最佳答案

看看你注册为传入请求处理程序的匿名函数:

func(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
go HandleIndex(w, r)
}

它打印 URL(到标准输出)然后在一个新的 goroutine 中调用 HandleIndex() 并继续执行。

如果你有一个处理函数,在第一次调用 Write 之前没有设置响应状态,Go 会自动将响应状态设置为 200(HTTP OK)。如果处理函数没有向响应写入任何内容(并且没有设置响应状态并正常完成),则也将其视为成功处理请求,并将返回响应状态 200。您的匿名函数没有设置它,它甚至没有向响应写入任何内容。所以 Go 会这样做:将响应状态设置为 200 HTTP OK。

请注意,处理每个请求都在其自己的 goroutine 中运行。

所以如果你在一个新的 goroutine 中调用 HandleIndex,你原来的匿名函数会继续:它会结束,所以响应头会被设置——同时(同时)你启动的新 goroutine 也会被设置响应头 - 因此 "multiple response.WriteHeader calls" 错误。

如果您删除 "go",您的 HandleIndex 函数将在您的处理函数返回之前将响应头设置在同一个 goroutine 中,并且“net/http”会知道这一点,不会再尝试设置响应头,所以你遇到的错误不会发生。

关于http - 多个 response.WriteHeader 在非常简单的示例中调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27972715/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com