大猩猩网络工具包:len(session.Flashes())为0

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

Gorilla web toolikit: len(session.Flashes()) is 0

问题

我有一个正在组合的注册表单,使用简单的逻辑在服务器端进行表单验证,例如:

if username == "" || len(username) < 5 {
    session.AddFlash("Username is too short")
    session.Save(r, w)
}

这个逻辑运行良好,然后在验证的最后,我进行以下操作(用于调试):

fmt.Println(len(session.Flashes())) // 返回 3

然后我检查是否有任何表单错误,如下所示:

if len(session.Flashes()) != 0 {
    // 执行重定向并显示错误信息
} else {
    // 设置正确的会话变量并登录用户
}

所以,如果 3 > 0,为什么触发的是 else 语句而不是 if 语句的第一部分呢?我不确定为什么会出现这种情况。如果需要更多信息,请告诉我。以下是实际的代码片段:

if username == "" || len(username) < 4 {
    session.AddFlash("Username is too short")
    session.Save(r, w)
}
if email == "" || len(email) < 5 {
    session.AddFlash("Email is too short")
    session.Save(r, w)
}
if firstname == "" || len(firstname) < 3 {
    session.AddFlash("Firstname is too short")
    session.Save(r, w)
}
if lastname == "" || len(lastname) < 3 {
    session.AddFlash("Lastname is too short")
    session.Save(r, w)
}

fmt.Println(len(session.Flashes()) > 0) // 返回 true

if len(session.Flashes()) != 0 {
    fmt.Println("为什么我也在这里")
    type Page struct {
        Title    string
        Username interface{}
        Errors   []interface{}
    }

    session, _ := common.GetSession(r)
    data := &Page{"Register", session.Values["username"], session.Flashes()}
    session.Save(r, w)

    tmpl, err := template.ParseFiles("views/register/register.html")
    if err != nil {
        http.Error(w, "加载页面失败。", 500)
    }
    tmpl.ExecuteTemplate(w, "register", data)
} else {
    fmt.Println("为什么我在这里")
    _, err := db.Query("// 执行数据库查询")
    if err != nil {
        http.Error(w, "抱歉,我们在将您的帐户保存到数据库时遇到问题,请稍后再试。", 500)
    }

    session.Values["username"] = r.FormValue("username")
    session.Values["authenticated"] = true

    session.Save(r, w)

    http.Redirect(w, r, "/", 303)
}
英文:

I have a register form I'm trying to put together, with simple logic I have form validation checked on the server side with simple ifs e.g.

if username == &quot;&quot; || &lt; 5 {
session.AddFlash(&quot;Username is too short&quot;)
session.Save(r, w)
}

That works fine then at the end of the validation I do (for debugging purposes)

fmt.Println(len(session.Flashes())) which returns 3

Then I check to see if there were any form errors like so

if len(session.Flashes()) != 0 {
// Perform Redirect and show flashes
} else {
// Set proper session variables and log user in
}

So if 3 &gt; 0 why is the else statement being triggered and not the first part of the if statement? I'm just unsure why this is happening the way it is. Thanks if you need anymore information let me know, actual code snippet:

if username == &quot;&quot; || len(username) &lt; 4 {
session.AddFlash(&quot;Username is too short&quot;)
session.Save(r, w)
}
if email == &quot;&quot; || len(email) &lt; 5 {
session.AddFlash(&quot;Email is too short&quot;)
session.Save(r, w)
}
if firstname == &quot;&quot; || len(firstname) &lt; 3 {
session.AddFlash(&quot;Firstname is too short&quot;)
session.Save(r, w)
}
if lastname == &quot;&quot; || len(lastname) &lt; 3 {
session.AddFlash(&quot;Lastname is too short&quot;)
session.Save(r, w)
}
fmt.Println(len(session.Flashes()) &gt; 0) // true
if len(session.Flashes()) != 0 {
fmt.Println(&quot;Why am I here also&quot;)
type Page struct {
Title    string
Username interface{}
Errors   []interface{}
}
session, _ := common.GetSession(r)
data := &amp;Page{&quot;Register&quot;, session.Values[&quot;username&quot;], session.Flashes()}
session.Save(r, w)
tmpl, err := template.ParseFiles(&quot;views/register/register.html&quot;)
if err != nil {
http.Error(w, &quot;Failed to load page.&quot;, 500)
}
tmpl.ExecuteTemplate(w, &quot;register&quot;, data)
} else {
fmt.Println(&quot;Why am I here&quot;)
_, err := db.Query(&quot;// Perform DB Query&quot;)
if err != nil {
http.Error(w, &quot;Sorry we had trouble saving your account to the database, try again in a bit.&quot;, 500)
}
session.Values[&quot;username&quot;] = r.FormValue(&quot;username&quot;)
session.Values[&quot;authenticated&quot;] = true
session.Save(r, w)
http.Redirect(w, r, &quot;/&quot;, 303)
}

答案1

得分: 1

这是要翻译的内容:

这段代码的文档不是很完善,但显然Flashes函数会从会话中移除闪存并返回它们:

func (s *Session) Flashes(vars ...string) []interface{} {
    var flashes []interface{}
    key := flashesKey
    if len(vars) > 0 {
        key = vars[0]
    }
    if v, ok := s.Values[key]; ok {
        // 删除闪存并返回它
        delete(s.Values, key)
        flashes = v.([]interface{})
    }
    return flashes
}

源代码在这里

这里的解决方案是使用一个单独的变量来保存验证状态:

valid := true
if username == "" || len(username) < 4 {
    valid = false
    session.AddFlash("用户名太短")
    session.Save(r, w)
}
// ...
if !valid {
    // ...
} else {
    // ...
}

编辑: 另一种获取闪存而不删除它们的方法是直接从Values中获取:

flashes := session.Values["_flash"].([]interface{})
英文:

It's not very well documented, but apparently Flashes removes flashes from the session and returns them:

func (s *Session) Flashes(vars ...string) []interface{} {
var flashes []interface{}
key := flashesKey
if len(vars) &gt; 0 {
key = vars[0]
}
if v, ok := s.Values[key]; ok {
// Drop the flashes and return it.
delete(s.Values, key)
flashes = v.([]interface{})
}
return flashes
}

Source code here.

The solution here is to use a separate variable to save the validation state:

valid := true
if username == &quot;&quot; || len(username) &lt; 4 {
valid = false
session.AddFlash(&quot;Username is too short&quot;)
session.Save(r, w)
}
// ...
if !valid {
// ...
} else {
// ...
}

EDIT: Another way to get flashes without deleting them is to get them from Values directly:

flashes := session.Values[&quot;_flash&quot;].([]interface{})

huangapple
  • 本文由 发表于 2015年8月26日 14:23:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/32219364.html
匿名

发表评论

匿名网友

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

确定