Go中HTTP响应头为何可在被调函数修改且未被后续WriteHeader覆盖
问题1解答
Go确实所有参数均为值传递,你传入LogExtractionErrorResponse的w虽然是值拷贝,但http.ResponseWriter属于接口类型。接口类型的值本身存储了两个信息:指向底层实现结构体的指针、底层类型的元信息。你拷贝的只是接口本身的这两个字段,底层对应的HTTP响应缓冲区对象始终是同一个,所以在common包函数中对w的所有操作都会作用在实际的响应对象上,400状态码的设置自然会生效。
问题2解答
Go标准库的http.ResponseWriter规定WriteHeader方法仅能生效一次:第一次调用该方法时,服务端就会把当前已设置的状态码、响应头刷入TCP连接发往客户端,后续所有对WriteHeader的调用都会被直接忽略,仅会在服务端后台打印一条superfluous response.WriteHeader call的警告日志,不会修改已经发出的状态码。
另外你在LogExtractionErrorResponse中还调用了w.Write写入响应体,这个操作本身就会强制触发响应头的发送流程,所以等回到外层Test handler再执行w.WriteHeader(http.StatusOK)时,响应头已经发送完成,自然不可能覆盖之前设置的400状态码。
最佳实践建议:错误响应逻辑执行完成后必须主动加
return终止handler后续逻辑,避免出现响应体拼接错乱、冗余警告日志等非预期问题。
内容的提问来源于stack exchange,提问作者Ashkanxy
相关产品推荐
相关产品推荐

