Web Form

https://github.com/bonfy/go-mega/blob/master/04-web-form.md

从这网站学的

随着我们项目的扩大,代码量会愈来愈多,我们需要建立这样的数据结构来使整个项目看起来没有那么臃肿

package model - 负责数据建模

vm - View Model,定义各种结构体来表示不同的视图模型

controller - http路由,就是对各个uri进行处理的函数,引用model包中的数据模型来执行业务逻辑,并使用vm包中的视图模型来准备数据以供渲染页面使用

g.go 负责存放该package的全局变量以及init函数

我直接开了一个新的文件夹来存放着一章的教程

下面我们来看一下这个login.html

{{define "content"}}
    <h1>Login</h1>
    <form action="/login" method="post" name="login">
        <p><input type="text" name="username" value="" placeholder="Username or Email"></p>
        <p><input type="password" name="password" value="" placeholder="Password"></p>
        <p><input type="submit" name="submit" value="Login"></p>
    </form>
{{end}}

我们看这段代码的表单第一行

<form action="/login" method="post" name="login"> 这里的action指定我们需要到这个目标URL

post是指表单提交的方法,post一般是指比较敏感的信息

name = "login"是指表单的名字是login,这样可以在JavaScript中通过这个名称来引用这个表单

JavaScript,css大家可以去菜鸟上了解一下基本的用途

<p><input type="text" name="username" value="" placeholder="Username or Email"></p>

主要解释一下placeholder,这个是指用户可以在其中输入用户名或电子邮件地址

value="" 表示输入字段的初始值为空

之前看过那个web基础,感觉这个类似于在做个项目,比go web基础好太多了,当然可能是我变强了,笑哭

接收表单数据

就是我们会发现我们在点login的时候,客户端的响应是没有的,只是说账号和密码都清空了,像qq它给的回应都是一个界面了对吧,我们这里只需要有个回应就好了,所以我们要对loginHandler进行修改

...

func loginHandler(w http.ResponseWriter, r *http.Request) {
    tpName := "login.html"
    vop := vm.IndexViewModelOp{}
    v := vop.GetVM()
    if r.Method == http.MethodGet {
        templates[tpName].Execute(w, &v)
      /*
      templates.Execute通常都是用模板来渲染画面的
      */
    }
    if r.Method == http.MethodPost {
        r.ParseForm()
        username := r.Form.Get("username")
        password := r.Form.Get("password")
        fmt.Fprintf(w, "Username:%s Password:%s", username, password)
    }
}
表单后端验证

一般验证用户名密码正确性检查只能在后端验证

我们在LoginViewModel里面添加一个Err字段,用于输出检查的错误返回

package vm

type LoginViewModel struct {
    BaseViewModel
    Errs []string
}

type LoginViewModelOp struct {
}

func (LoginViewModelOp) GetVM() LoginViewModel {
    v := LoginViewModel{}
    v.SetTitle("Login")
    return v
}
func (v *LoginViewModel) AddError(errs ...string) {
    v.Errs = append(v.Errs, errs...)
}

我们主要来解析一下新增的login.html代码

这里就不按照

...
    {{if .Errs}} <!--判断属性Errs是否为空,如果不为空-->
    <ul>   <!--ul表示无序列表,无序列表中通常以项目符号表示-->
        {{range .Errs}}
            <li>{{.}}</li><!--每个列表项使用<li>标签来定义-->
         {{end}}
    </ul>
    {{end}}
...

我们在controller中的home.go中新增check方法和修改loginHandler方法

...

func check(username, password string) bool {
    if username == "bonfy" && password == "abc123" {
        return true
    }
    return false
}


func loginHandler(w http.ResponseWriter, r *http.Request) {
    tpName := "login.html"
    vop := vm.LoginViewModelOp{}
    v := vop.GetVM()
    //因为客户端在访问的时候其实是get方法
    //在提交信息的时候是POST方法
    if r.Method == http.MethodGet {
        templates[tpName].Execute(w, &v)
    }
    if r.Method == http.MethodPost {
        r.ParseForm()
        username := r.Form.Get("username")
        password := r.Form.Get("password")
        if len(username) < 3 {
            v.AddError("username must longer than 3")
        }

        if len(password) < 6 {
            v.AddError("password must longer than 6")
        }
        if !check(username, password) {
            v.AddError("username password not correct,please input again")
        }

        if len(v.Errs) > 0 { //重新执行这个模板,然后显示这个错误
            templates[tpName].Execute(w, &v)
        } else {
            http.Redirect(w, r, "/", http.StatusSeeOther)//成功的话就会转到一个新的网站
        }
        fmt.Fprintf(w, "Username:%s Password:%s", username, password)
    }
}

这里提醒一下大家,那个html文件改变较大,如果出错了,可以重点看一下那个文件

{{define "content"}}
<h1>Login</h1>
<form action="/login" method="post" name="login">
    <p><input type="text" name="username" value="" placeholder="Username or Email"></p>
    <p><input type="password" name="password" value="" placeholder="Password"></p>
    <p><input type="submit" name="submit" value="Login"></p>
</form>
{{if .Errs}}
<ul>
    {{range .Errs}}
    <li>{{.}}</li>
    {{end}}
</ul>
{{end}}
{{end}}

等会要调试一下,看一下怎么走的,总结一下

就是注册一个路由处理器,里面有路由处理器,对每个uri路径进行处理

相关推荐

  1. WebForms Hashtable

    2024-04-08 15:00:04       28 阅读
  2. WebForms SortedList 排序列表

    2024-04-08 15:00:04       29 阅读
  3. ASP.NET-WebFoms常见前后端交互方式

    2024-04-08 15:00:04       46 阅读
  4. webform使用ajax访问后端接口的两种方法

    2024-04-08 15:00:04       56 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-08 15:00:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-08 15:00:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-08 15:00:04       87 阅读
  4. Python语言-面向对象

    2024-04-08 15:00:04       96 阅读

热门阅读

  1. 设计模式面试题(八)

    2024-04-08 15:00:04       43 阅读
  2. Mysql服务器主从相关

    2024-04-08 15:00:04       32 阅读
  3. 嵌入式算法开发系列之归一化算法

    2024-04-08 15:00:04       37 阅读
  4. 面试前端八股文十问十答第八期

    2024-04-08 15:00:04       37 阅读
  5. mysql锁

    mysql锁

    2024-04-08 15:00:04      28 阅读
  6. docker 之 基本命令

    2024-04-08 15:00:04       33 阅读
  7. docker build 构建不出新镜像一直都是老镜像

    2024-04-08 15:00:04       34 阅读
  8. 第十四届蓝桥杯c++组B组做题笔记

    2024-04-08 15:00:04       35 阅读
  9. AJAX

    AJAX

    2024-04-08 15:00:04      42 阅读