Go语言 在处理程序内使用“Write”方法,标头保持为空,但是,对于“ServeFile”函数,这不是真的,为什么会发生这种情况?

yyhrrdl8  于 2023-01-18  发布在  Go
关注(0)|答案(1)|浏览(121)

我正在学习golang处理程序,但有一些误解。它与响应头关联。当我使用http.ServeFile函数时,它将按我所期望的填充响应头。以下是代码和输出:

mux := http.NewServeMux()

mux.HandleFunc("/nesto", func(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "./ui/static/js/main.js")
    fmt.Println("Header:", w.Header())
})

http.ListenAndServe(":4000", mux)

输出:

Header: map[Accept-Ranges:[bytes] Content-Length:[224] Content-Type:[application/javascript] Last-Modified:[Thu, 05 Jul 2018 13:44:05 GMT]]

对我来说这是预期的行为,因为它的第一个参数是http.ResponseWriter,并且将在内部使用Write方法写入响应主体。

// If WriteHeader has not yet been called, Write calls
// WriteHeader(http.StatusOK) before writing the data. If the Header
// does not contain a Content-Type line, Write adds a Content-Type set
// to the result of passing the initial 512 bytes of written data to
// DetectContentType. Additionally, if the total size of all written
// data is under a few KB and there are no Flush calls, the
// Content-Length header is added automatically.

所以,对我来说完全正常的行为。
但是当我直接使用Write方法时,Header仍然是空的。

mux := http.NewServeMux()

mux.HandleFunc("/nesto", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Some message."))
    fmt.Println("Header:", w.Header())
})

http.ListenAndServe(":4000", mux)

输出:

Header: map[]

为什么会发生这种情况?Header不应该被填充吗?毕竟文档本身(关于方法的注解)是这么说的?

pkwftd7m

pkwftd7m1#

文档描述了写入网络的标头,而不是响应编写器Header()。
文档有点草率。在WriteHeader之前调用Write触发了文档中描述的操作。这些操作不一定在第一次调用Write时执行:

  • 在调用DetectContentType之前,服务器等待应用程序写入512字节的数据或处理程序返回。
  • 服务器缓冲了几KB的数据,如果处理程序返回并且缓冲区还没有被刷新到网络,那么服务器会在写入网络的头中添加一个内容长度。

请参阅代码了解更多详细信息。
在调用ServeFile后,您会看到内容长度和内容类型标头,因为ServeFile在响应编写器Header()中显式设置了这些标头。内容长度设置为磁盘上文件的大小。内容类型使用文件扩展名设置。

相关问题