dousi6087 2016-02-08 18:12 采纳率: 100%
浏览 426
已采纳

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

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):

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". 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!!!

  • 写回答

2条回答 默认 最新

  • dpsx99068 2016-02-08 23:27
    关注

    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. 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. 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? 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?