从有关
http.ResponseWriter方法的文档中:(
添加了重点)
Header() http.Header
:
除非修改后的标头是预告片,否则在 调用WriteHeader(或Write)后 更改标头映射 无效 。
WriteHeader(statusCode int)
:
WriteHeader 发送 带有提供的状态代码 的HTTP响应标头 。
Write([]byte) (int, error)
:
如果尚未 调用WriteHeader ,则Write 在写入数据之前会 调用WriteHeader(http.StatusOK) 。
这应该强调为什么,你不能设置在后一个cookie的原因
next.ServeHTTP(w,r)调用,这是在通过电话执行的中间件链中的处理程序中的一个或者打电话
WriteHeader或
Write直接或间接的。
因此,要能够在调用 之后 设置cookie ,
next.ServeHTTP(w,r)您需要确保中间件链调用
WriteHeader或
Write原始
http.ResponseWriter实例中没有任何处理程序。一种方法是将原始实例包装在自定义
http.ResponseWriter实现中,该实现将
推迟 响应的编写,直到完成cookie设置为止。
例如这样的事情:
type responsewriter struct { w http.ResponseWriter buf bytes.Buffer pre int}func (rw *responsewriter) Header() http.Header { return rw.w.Header()}func (rw *responsewriter) WriteHeader(statusCode int) { rw.pre = statusCode}func (rw *responsewriter) Write(data []byte) (int, error) { return rw.buf.Write(data)}func (rw *responsewriter) Done() (int64, error) { if rw.pre > 0 { rw.w.WriteHeader(rw.pre) } return io.Copy(rw.w, &rw.buf)}
您可以在中间件中像这样使用它:
func handler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rw := &responsewriter{w: w} next.ServeHTTP(rw, r) if r.Method == "POST" && r.URL.String() == "/login" { foo := rw.Header().Get("X-FOO") setcookie(rw, "MYAPPFOO", foo) } if _, err := rw.Done(); err != nil { log.Println(err) } })}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)