Golang在模板执行后setCookie()失败。

huangapple go评论95阅读模式
英文:

Golang setCookie() failed after template Execute()

问题

作为GO的初学者,我遇到了以下情况:

t, err := template.ParseFiles("/template/login.tpl")

err = t.Execute(w, nil)         //如果在SetCookie之前执行

http.SetCookie(...)			 //失败,浏览器没有接收到任何内容

如果更改顺序,先执行SetCookie,它就会起作用。

我的计划是在login.tpl中通过ParseForm()解析用户名和密码,如果成功,SetCookie将发送一个sessionID。但现在必须在login.tpl被执行之前放置SetCookie(),这也使得ParseForm()login.tpl被执行之前运行:

r.ParseForm()                          //即使在模板执行之前,ParseForm()也会起作用

email := r.FormValue("email")
pass := r.FormValue("pass")

var loginPass = checkLogin(email, pass) //验证用户名和密码

if loginPass == true {                  //如果正确

    cookie1 := http.Cookie{Name: "test", Value: "testvalue", Path: "/", MaxAge: 86400}
    http.SetCookie(w, &cookie1)         //setCookie起作用

    fmt.Println("登录成功:", email)

} else {                                //如果用户名或密码不正确

    fmt.Println("请登录:", email)

}

t, err := template.ParseFiles("/template/login.tpl")
err = t.Execute(w, nil)                 //现在模板执行在这里,也起作用

但为什么要这样写呢?请有经验的人给我一些建议!非常感谢。

英文:

As a beginner of GO, I've got a situation as following:

t, err := template.ParseFiles("/template/login.tpl")

err = t.Execute(w, nil)         //if executed before SetCookie

http.SetCookie(...)			 //failed, browser received nothing

If the sequence is changed, to SetCookie first, it'll work.

My plan was to ParseForm() username and password in login.tpl, if success, a sessionID would be sent by SetCookie. But now SetCookie() must be placed before login.tpl is Executed, which also makes ParseForm() run before login.tpl is executed :

r.ParseForm( )                          //ParseForm() works even before template is executed

email := r.FormValue("email")
pass := r.FormValue("pass")

var loginPass = checkLogin(email, pass) //verify username and password

if loginPass == true {                  //if correct

    cookie1 := http.Cookie{Name: "test", Value: "testvalue", Path: "/", MaxAge: 86400}
    http.SetCookie(w, &cookie1)         //setCookie works

    fmt.Println("Login success: ", email)

} else {                                //if incorrect username or pass

    fmt.Println("Please login: ", email)

}

t, err := template.ParseFiles("/template/login.tpl")
err = t.Execute(w, nil)                 //now template execution is here, also works

But why it should be written like this? Please anyone give me some advice! Thanks a lot.

答案1

得分: 3

这是与HTTP协议相关的常见错误:cookie是在HTTP响应的头部中发送的,在开始发送正文后无法更改。

因此,当你调用t.Execute(w, nil)时,你开始编写响应的正文,因此无法在此之后添加cookie。

这正是为什么在PHP中,session_start()调用必须是页面的第一条指令,甚至在任何空白字符之前的确切原因。

英文:

This is a common error tied to the HTTP protocol working: the cookie is sent in a header of the HTTP respo7nse, which cannot be changed after the body start being sent.

So, when you do the t.Execute(w, nil) call, you start writing the body of the response and thus cannot add cookies afterwards.

This is the exact same reason why in PHP the session_start() call must be the very first instruction of the page, even before any whitespace.

huangapple
  • 本文由 发表于 2016年3月17日 01:02:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/36042298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定