有个场景,是页面在不断地使用fmt.Fprintf(w, "something...")进行输出,其中w被定义为w http.ResponseWriter。需求是在输出完成后,页面自动进行一次跳转,或者说重定向。首先想到使用http.Redirect进行重定向,结果发现报错:
http: superfluous response.WriteHeader call from
第一反应是纳闷:我之前也没调用过w.WriteHeader函数啊,为啥会报错捏?
首先,使用http.Redirect(w, r, "https://example.com", http.StatusFound)是不行的,这是因为在WriteHeader的手册里,有这么一段话:
If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.
大意是说,WriteHeader存在隐式调用。若Write先呼叫时会自动预设状态码为http.StatusOK,因此后续再呼叫WriteHeader时就会变成多重写入状态码的问题发生,导致客户端收到不正确的状态。
也就是说,fmt.Fprintf(w, "something...")中,调用w进行写操作已经触发了对w.WriteHeader的隐式调用。
所以疑问解开了。那应该怎么解决这个需求呢?其实很简单,因为fmt.Fprintf(w, "something...")中是可以传入html代码的!因此只要进行如下操作即可:
// 前提是w已经加载为html网页,
// 类似:fmt.Fprint(w, "<html><head><title></title></head><body></body></html>")
// 或者:tmpl, err := template.ParseFiles("xxx.html"), err = tmpl.Execute(w, nil)
fmt.Fprintf(w, "something1...")
fmt.Fprintf(w, "something2...")
// ...
// 输出完成,准备自动重定向(window.location.replace("url")或者window.location.href="url"选一个需要的)
// 别忘了加<script>标签
fmt.Fprintf(w, "<script>window.location.href=\"https://example.com/\";</script>")
// ...

被折叠的 条评论
为什么被折叠?



