简体   繁体   English

Golang:两次重定向并导致http:多次响应。WriteHeader调用

[英]Golang: redirect twice and cause http: multiple response.WriteHeader calls

I have a very weird output ... let me post my code first then I will explain: 我的输出很奇怪...让我先发布代码,然后再解释:

Under main function I declared 在我声明的主要功能下

manageMux.HandleFunc("/info", info)

first I log in and redirect from "/login" to page "/": 首先,我登录并从“ /登录”重定向到页面“ /”:

func login(w http.ResponseWriter, r *http.Request) {
    if r.Method == "GET" {
        t, err := template.ParseFiles("manage/login.html")
        checkError(err)
        t.Execute(w, nil)
    } else { //POST
        r.ParseForm()
        //do some authentications here
        http.Redirect(w, r, "/", http.StatusFound)
    }
}

Then I redirect to another page "/info" from current page "/" (which has only buttons): 然后,我从当前页面“ /”(只有按钮)重定向到另一个页面“ / info”:

func manage(w http.ResponseWriter, r *http.Request) {
    t, err := template.ParseFiles("manage/manage.html")
    checkError(err)
    t.Execute(w, nil)
    r.ParseForm()
    if r.Form["Button"] != nil { //to get only POST actions from buttons
        if r.Form["Button"][0] == "Log" {
            http.Redirect(w, r, "/info", http.StatusFound)
        } 
    }
}

At last, I made a template and would like to show on client side: 最后,我制作了一个模板,想在客户端显示:

const tpl=`stuff inside`

type InfoDefault struct {
    //stuff inside
}

func info(w http.ResponseWriter, r *http.Request) {
    info := InfoDefault{
        //stuff inside
    }

    t, err := template.New("info").Parse(tpl)
    checkError(err)
    err = t.Execute(os.Stdout, info)
    checkError(err)
}

Now, the weird thing is, when I click the button on page "/", I got the error "http: multiple response.WriteHeader calls". 现在,奇怪的是,当我单击页面“ /”上的按钮时,出现了错误“ http:多个response.WriteHeader调用”。 At the same time a link called "found" shows up on the bottom of my page (weird!), and when I click the link "found", I got all my parsed template printed on the server side instead of webpage. 同时,在页面底部显示一个名为“找到”的链接(很奇怪!),当我单击链接“找到”时,我将所有解析的模板打印在服务器端而不是网页上。

Does anyone know why...? 有谁知道为什么...? And how to fix the error and print stuff on client webpage? 以及如何解决错误并在客户端网页上打印内容? Thank you!!! 谢谢!!!

As JimB already pointed out: your server gets confused because there are different status codes associated with both writing to http.ResponseWriter and the redirect . 正如JimB所指出的:您的服务器感到困惑,因为写入http.ResponseWriterredirect都有不同的状态代码。 You can't do both at the same time. 您不能同时执行两项操作。

I would actually like to expand more on how you can carry data over to the next page (assuming you are redirecting). 实际上,我想进一步扩展如何将数据传送到下一页(假设您正在重定向)。

Headers You can write some information to the request object and receive it on the destination page. 标头您可以将一些信息写入请求对象,并在目标页面上接收它。 Example: 例:

func myHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("My-Awesome-Header", "Rocks")
    ...
}

Session: You are talking about access control as far as I can see, and I think persisting user data is better done through a session. 会话:据我所知,您正在谈论访问控制,我认为通过会话更好地保存用户数据。 Example: you can use a database or a session handler like https://github.com/gorilla/sessions . 示例:您可以使用数据库或会话处理程序,例如https://github.com/gorilla/sessions Check out this thread: Best practice with sessions (gorilla/sessions) . 查看此线程: 会话最佳实践(大猩猩/会话)

Cookies: I'm not sure what kind of front-end you are using, but storing non-sensitive data on the cookie could be an option? Cookies:我不确定您使用的是哪种前端,但是可以在cookie上存储非敏感数据吗? Nothing beats this one (it has real choc-chip cookies in the examples ;-) ): https://astaxie.gitbooks.io/build-web-application-with-golang/content/en/06.1.html . 没有什么比这更好的了(示例中包含真正的choc-chip cookie ;-)): https : //astaxie.gitbooks.io/build-web-application-with-golang/content/en/06.1.html

In your manage handler, you're executing the template which will write to the http.ResponseWriter and trigger an http.StatusOK (200) status code. 在您的manage处理程序中,您正在执行模板,该模板将写入http.ResponseWriter并触发http.StatusOK (200)状态代码。 You can't redirect after that, since that requires sending a different response code. 之后,您将无法重定向,因为这需要发送其他响应代码。

If you need to redirect, do it before executing the template. 如果需要重定向,请在执行模板之前进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM