Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在GO中的http处理程序函数之间传递数据_Http_Go - Fatal编程技术网

在GO中的http处理程序函数之间传递数据

在GO中的http处理程序函数之间传递数据,http,go,Http,Go,我有一个http处理程序功能,它只在尚未接收电子邮件时才将电子邮件保存到数据库。如果电子邮件已被接收或其他数据无效,我希望重定向回表单并通知用户错误发生的位置 func validate(w http.ResponseWriter, r *http.Request) { //query database to check if data r.FormValues were //valid //IF form values were not valid redirect

我有一个http处理程序功能,它只在尚未接收电子邮件时才将电子邮件保存到数据库。如果电子邮件已被接收或其他数据无效,我希望重定向回表单并通知用户错误发生的位置

func validate(w http.ResponseWriter, r *http.Request) {

    //query database to check if data r.FormValues were
    //valid

    //IF form values were not valid redirect back to the
    //registration form and  pass on data indicating the
    //form data was not valid
    {
        http.Redirect(w, r, "/register", http.StatusFound)
    }

}

我究竟如何将数据从func validate()发送到func register()?是否可以向r*http.Request添加某种结构,以便在调用http.Redirect()时将其传递给func register(),浏览器将再次调用
/register
。您的
validate()
处理程序和
register()
处理程序之间没有连接,
*http.Request
值将与浏览器发出另一个http请求的值不同,因此将创建另一个
*http.Request
值并在第二次调用时传递

您可以在重定向URL中指定参数,例如重定向到
/register?someParam=someValue
,但这只是一个不必要的往返过程,会使事情复杂化

一个更简单的解决方案是不分离表单呈现和验证(在处理程序级别)。同一个处理程序可以同时处理这两个问题,因此两个处理程序之间不需要共享数据

例如:

func register(w http.ResponseWriter, r *http.Request) {
    // Params for rendering the page
    m := map[string]interface{}{}

    // Is form submitted?
    if r.FormValue("submitRegister") != "" {
        // check submitted values
        // E.g. check email, let's say it's already in use:
        email := r.FormValue("Email")
        if alreadyInUse {
            m["Error"] = "Email already in use!"
        }

        if m["Error"] == "" {
            // If all values are OK, create user, and redirect:
            http.Redirect(w, r, "/home", http.StatusFound)
            return // AND return!
        }

        // Store submitted values in params, so when we render
        // the registration form again, we fill submitted params as initial values,
        // so user don't have to fill everything again (expect maybe the password)
        m["Email"] = email
    }

    // Either no submit or validation errors
    // Render the registration form, using submitted values as initial ones
    // Also if m["Error"] is set, render the error above the form
    registerTempl.Execute(w, m)
}
当然,您可以将其分解为函数,也可以使用单独的
validate()
函数,但表单提交必须指向与注册页面相同的路径(例如
/register
):


非常感谢,伊卡。在一个处理函数中完成所有操作似乎是一个更优雅的解决方案。
func register(w http.ResponseWriter, r *http.Request) {
    // Params for rendering the page
    m := map[string]interface{}{}

    // Is form submitted?
    if r.FormValue("submitRegister") != "" {
        validate(w, r, m)
        if m["Error"] == "" {
            return // AND return!
        }
    }

    // Either no submit or validation errors
    // Render the registration form, using submitted values as initial ones
    // Also if m["Error"] is set, render the error above the form
    registerTempl.Execute(w, m)
}

func validate(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {
    // check submitted values
    // E.g. check email, let's say it's already in use:
    email := r.FormValue("Email")
    if alreadyInUse {
        m["Error"] = "Email already in use!"
    }

    if m["Error"] == "" {
        // If all values are OK, create user, and redirect:
        http.Redirect(w, r, "/home", http.StatusFound)
        return
    }

    // Store submitted values in params, so when we
    // render the registration form again, we fill submitted params as initial values,
    // so user don't have to fill everything again (expect maybe the password)
    m["Email"] = email
}