type
Post
status
Published
date
Dec 3, 2022
slug
golang-header-write
summary
最近开发中要对 HTTP Header 进行一些操作,记录一下不会特别注意但容易造成问题的地方
tags
开发
Golang
category
技术分享
icon
password

ResponseWriter.Write 会导致客户端收到错误的 HTTP 状态码

 
首先看看下面这段代码,猜猜看客户端会收到什么样的状态码?
// server.go http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello")) w.WriteHeader(http.StatusBadRequest) })
觉得应该是 400 Bad Request? No no no, 正确答案是 200 ok
$ curl -i http://127.0.0.1:8080 HTTP/1.1 200 OK Date: Fri, 02 Dec 2022 13:11:53 GMT Content-Length: 6 Content-Type: text/plain; charset=utf-8 Hello
并且会在控制台打印出以下 log
2022/12/02 13:11:53 http: multiple response.WriteHeader calls
造成这个的原因是 WriteHeader 和 Write 的调用顺序,官方文档中对于这个问题是这样解释的
If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK).
也就是说,如果先调用 Write,就会自动将状态码设置为 http.StatusOK,而后续再调用 WriteHeader 就会导致多次写入状态码,会使客户端无法收到正确的状态
 
所以如果要想返回正确的错误发,需要先调用 WriteHeader 设置状态码,再调用 Write 写入 body
 
Promise:All 还是 AllSettled 是个问题Golang 那些事:HTTP Header 的那些坑(2)