为什么在gin的方法*Context.Render(code int, r render.Render)中先设置response code?
Why response code is set firstly in method *Context.Render(code int, r render.Render) of gin?
Gin封装了一些构造response的方法,比如方法*Context.JSON(code int, obj interface{})
和*Context.String(code int, format string, values ...interface{})
。这些方法都是调用方法*Context.Render(code int, r render.Render)
.
// Render writes the response headers and calls render.Render to render data.
func (c *Context) Render(code int, r render.Render) {
c.Status(code)
if !bodyAllowedForStatus(code) {
r.WriteContentType(c.Writer)
c.Writer.WriteHeaderNow()
return
}
if err := r.Render(c.Writer); err != nil {
panic(err)
}
}
我想知道为什么Render
方法会调用Status
方法,它会先调用ResponseWriter.WriterHeader(statusCode int)
方法来设置HTTP响应码。
r.Render(c.Writer)
会将相应的 Content-Type 写入响应。显然它发生在设置状态代码之后(调用方法 WriterHeader
之后)。根据对方法 ResponseWriter.Header()
的评论,在调用 WriteHeader
(或 Write
)后更改 header 映射没有任何效果,除非修改后的 header 是拖车。但是设置 Content-Type 在 Gin 中有效。
func writeContentType(w http.ResponseWriter, value []string) {
header := w.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = value
}
}
c.Writer
是 gin.ResponseWriter
(可能是具体类型 gin.responseWriter
),而不是 http.ResponseWriter
。虽然它实现了相同的接口,但的实现方式不同。 Gin 的 WriteHeader
不会 立即发送 headers;它只是将 code
存储在编写器内部,WriteHeaderNow
使用存储的代码从 net/http
调用“真实的”WriteHeader
。
WriteHeaderNow
在没有body的情况下直接被你引用的函数调用;如果有 body,则 WriteHeaderNow
在第一个 Write
到 body 被调用。
Gin封装了一些构造response的方法,比如方法*Context.JSON(code int, obj interface{})
和*Context.String(code int, format string, values ...interface{})
。这些方法都是调用方法*Context.Render(code int, r render.Render)
.
// Render writes the response headers and calls render.Render to render data.
func (c *Context) Render(code int, r render.Render) {
c.Status(code)
if !bodyAllowedForStatus(code) {
r.WriteContentType(c.Writer)
c.Writer.WriteHeaderNow()
return
}
if err := r.Render(c.Writer); err != nil {
panic(err)
}
}
我想知道为什么Render
方法会调用Status
方法,它会先调用ResponseWriter.WriterHeader(statusCode int)
方法来设置HTTP响应码。
r.Render(c.Writer)
会将相应的 Content-Type 写入响应。显然它发生在设置状态代码之后(调用方法 WriterHeader
之后)。根据对方法 ResponseWriter.Header()
的评论,在调用 WriteHeader
(或 Write
)后更改 header 映射没有任何效果,除非修改后的 header 是拖车。但是设置 Content-Type 在 Gin 中有效。
func writeContentType(w http.ResponseWriter, value []string) {
header := w.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = value
}
}
c.Writer
是 gin.ResponseWriter
(可能是具体类型 gin.responseWriter
),而不是 http.ResponseWriter
。虽然它实现了相同的接口,但的实现方式不同。 Gin 的 WriteHeader
不会 立即发送 headers;它只是将 code
存储在编写器内部,WriteHeaderNow
使用存储的代码从 net/http
调用“真实的”WriteHeader
。
WriteHeaderNow
在没有body的情况下直接被你引用的函数调用;如果有 body,则 WriteHeaderNow
在第一个 Write
到 body 被调用。