解决Golang WriteHeader设置后,Content-Type失效的问题
2024-01-02 22:09:08
场景
最近笔者在研究web框架过程中,发现了一个响应类型的问题,困扰许久,原因就是设置了响应状态码后,然后设置响应类型为application/json
。在实际请求后,响应类型变成了text/plain; charset=utf-8
格式。
问题解决:
先设置请求头的Content-type属性,再设置响应状态码,即可解决问题
// 例如: func writeContentType(w http.ResponseWriter) { header := w.Header() if val := header["Content-Type"]; len(val) == 0 { header["Content-Type"] = []string{"application/json; charset=utf-8"} } } // 先执行 writeContentType(w) // 再执行 w.WriteHeader(code)
分析导致问题的原因
我们处理请求接收的参数是:http.ResponseWriter
类型的,它是一个接口类型,只要实现了这个接口都可以作为参数传递进来。
而实际传递进来的是:response
结构体,它实现了http.ResponseWriter
接口
可以通过定位
http.ResponseWriter
结构体,在同文件里面找到response结构体
我们查看一下response
结构体的WriteHeader
方法的源码,里面有一段代码:
func (w *response) WriteHeader(code int) {
// 忽略代码
if w.calledHeader && w.cw.header == nil {
w.cw.header = w.handlerHeader.Clone()
}
// 忽略代码
}
再看一下response
结构体的Header
方法(因为我们实际就是调用它,然后设置响应头的):
func (w *response) Header() Header {
if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
w.cw.header = w.handlerHeader.Clone()
}
w.calledHeader = true
return w.handlerHeader
}
总结问题:
通过分析上面两组代码可以发现,如果我们先执行了WriteHeader
方法,它会给w.cw.header
设置值,此时我们再调用Header
方法设置Content-type
属性时,经过if
判断,w.cw.header
并不等于nil
了,所以我们给header设置的属性无法设置到w.cw.header
上面,导致实际响应时,content-type
发生变化。关键点就在于w.cw.header
这个字段,如果设置的属性没到它上面的话,会导致失效。
文章来源:https://blog.csdn.net/m0_46958731/article/details/135274575
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!