关于Go net/http包ResponseWriter接口的两个技术疑问
关于Go语言net/http包ResponseWriter的两个疑问解答
代码示例
package main import ( "fmt" "net/http" "os" ) type handler struct{} func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Method: %v\n", req.Method) fmt.Fprintf(w, "URL: %v\n", req.URL) fmt.Fprintf(w, "Protocol: %v\n", req.Proto) fmt.Fprintf(os.Stdout, "Header: %v\n", w.Header()) } func main() { http.ListenAndServe(":8080", &handler{}) }
测试命令及结果
C:\Users>curl -i -X GET localhost:8080 HTTP/1.1 200 OK Date: Fri, 19 Aug 2022 03:47:21 GMT Content-Length: 38 Content-Type: text/plain; charset=utf-8 Method: GET URL: / Protocol: HTTP/1.1
疑问1解答:未实现ResponseWriter接口为何能正常运行?
你不需要自己实现ResponseWriter接口,因为net/http框架内部已经预先实现了满足该接口的具体类型。当ListenAndServe启动服务后,每收到一个HTTP请求,框架会自动创建一个对应请求的响应写入器实例(比如内部的response类型),这个实例已经完整实现了ResponseWriter定义的Header()、Write()、WriteHeader()方法,随后会将这个实例作为参数传入你的ServeHTTP方法。你只需要在方法中调用接口提供的能力即可,底层实现完全由框架处理。
疑问2解答:w.Header()返回空map,但curl能看到响应头?
这是因为框架自动添加的默认响应头,并不会提前出现在w.Header()返回的集合中:
- 你调用
fmt.Fprintf(w, ...)时会触发Write方法,此时若未手动设置响应头,框架会先写入默认状态码200 OK,但Date、Content-Type这类默认响应头,是在响应即将发送给客户端的最后阶段,由框架自动补充的,不会在你调用w.Header()时就存在于返回的map里。 w.Header()返回的是供你自定义修改的响应头集合,如果你手动添加一个自定义头(比如w.Header().Add("X-Custom", "demo")),再打印就能看到这个头出现在map中了。
内容的提问来源于stack exchange,提问作者M.S.
相关产品推荐
相关产品推荐

