我从戈朗那里得到了一个非常奇怪的行为。
我想用post请求做一些事情,然后重定向请求。根据随机因素…它是否有效。
当它不工作时,我得到这个错误:
“http:多余的响应。WriteHeader调用来自...”
在函数中越深,重定向将工作的可能性越小。
- 据我所知,我只重定向了一次(或零次...)
- 在重定向之前,我不会写入标题。
- 在重定向之前,我对writer所做的唯一一件事就是将其放入Map中。
我不想复制所有的代码在这里,所以我会总结一下。
处理程序处理POST请求,在名为demand
的Map中传递请求数据。
然后解析请求以获取表单值,并将其保存到demand
中,然后发送到通道中。
需求图从通道传递到以下函数:
func answer_login(demand map[string]any) map[string]any {
writer := demand["writer"].(http.ResponseWriter)
request := demand["request"].(*http.Request)
http.Redirect(writer, request, "/", 302) // <- if it is here it works (at95 %)
// some mundane code (printing stuff, really)
.
.
.
// http.Redirect(writer, request, "/", 302) // <- if it is here it works (only at 20 %)
...
如果我按下F5键,它最终会正确重定向。我试着简单地写一些东西到writer.Write([]byte("same issue"))
,同样的问题。
我在Linux上,我尝试了不同的浏览器。
问题:这是一个已知的bug吗?
是否有变通办法?
(强制写入客户端)
thx
1条答案
按热度按时间enyaitl31#
我终于对这个问题有了一个了解和解决方案。
问题:
然后解析请求以获取表单值,并将其保存到发送到通道的需求中。需求图从通道被传递到下面的函数…
因此,writer-request在一个函数中被处理和重定向,该函数与 actual handler函数处于不同的作用域。以及 actual handler函数何时结束。一些上下文的东西使writer-request过期:您不能再重定向或响应该请求。这是在doc中写的:
HTTP处理程序使用ResponseWriter接口来构造HTTP响应。在Handler.ServeHTTP方法返回后,不能使用ResponseWriter。
https://pkg.go.dev/net/http
关于为什么它有时会起作用的一个可能的解释是...也许“通道传输,处理和重定向”发生得足够快(有时),并且 * 实际 * 处理程序功能尚未关闭。
阻塞处理函数直到数据被处理,这就扼杀了并行异步处理的目的。所以我最终把所有的都嵌套在处理函数中。
欢迎聪明的人纠正我或分享关于上下文和ResponseWriters的更好解释。