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 vmtype LoginViewModel struct {BaseViewModelErrs []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路径进行处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/795381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】增删改查操作(基础)

文章目录 1、新增操作&#xff08;Create&#xff09;1.1单行数据全列插入1.2多行数据指定列插入 2、查询操作&#xff08;Retrieve&#xff09;2.1全列查询2.2指定列查询2.3指定列查询2.4别名&#xff08;as&#xff09;2.5去重&#xff08;distinct&#xff09;2.6排序&#…

机器学习实战18-机器学习中XGBClassifier分类器模型的应用实战,以及XGBClassifier分类器的调优策略

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战18-机器学习中XGBClassifier分类器模型的应用实战&#xff0c;以及XGBClassifier分类器的调优策略。XGBClassifier是基于eXtreme Gradient Boosting (XGBoost)算法的分类器模型&#xff0c;在机器学习领…

[Semi-笔记]Switching Temporary Teachers for Semi-Supervised Semantic Segmentation

目录 概要创新一&#xff1a;Dual Temporary Teacher挑战&#xff1a;解决&#xff1a; 创新二&#xff1a;Implicit Consistency Learning&#xff08;隐式一致性学习&#xff09;挑战&#xff1a;解决&#xff1a; 实验结果小结论文地址代码地址 分享一篇2023年NeurIPS的文章…

python 利用xpath 爬取一周天气

需求&#xff1a; 爬取 中国天气网指定城市一周的天气&#xff0c;以天津为例 实现&#xff1a; 1&#xff0c;先找到一周的数据位置。 divs html.xpath("//div[classhanml]") 2&#xff0c;再遍历每天。 trs div.xpath("./div/div[2]/table//tr[position…

PC发送指令给单片机控制LED(与上一篇文章相反)

此时要重新配置寄存器 &#xff0c;实现电脑往单片机传输数据 1、配置SCON寄存器的REN 即 REN 1 2、有TI&#xff08;发送中断&#xff09;就有RI&#xff08;接收中断&#xff09; 3、优化 发现发送 o 时&#xff0c;D5亮灯会有延迟 下面就是做到真正的无延迟的全双工通信 …

day11 基础函数(二)

知识回顾 ```python # 函数:封装具有某种功能的代码块 函数的定义 def 函数名(): 代码 函数名() # 函数调用 实参:相当于变量值(演员) 形参:相当于变量名(角色) 必须参数(位置参数) 就是必须按照正确的顺序将实参传入到函数中,实参和形参个数必须一一对应 默认参数 de…

深入理解计算机系统 家庭作业 2.85

A 7111.01.11*V E2,M1.11,f0.11 位表示: exp:10000...001其中0有k-2个.frac:1100...000其中0有n-2个 B 有个默认条件就是E>n, En,M1.111...(小数部分n个1),f0.1111(n个1),V exp:111...11其中1有n-1个.frac:111...111其中1有n个 C有个默认条件就是没有符号位.最小的规格…

JS详解-设计模式

工厂模式&#xff1a; 单例模式&#xff1a; // 1、定义一个类class SingleTon{// 2、添加私有静态属性static #instance// 3、添加静态方法static getInstance(){// 4、判断实例是否存在if(!this.#instance){// 5、实例不存在&#xff0c;创建实例this.#instance new Single…

Android 关于apk反编译d2j-dex2jar classes.dex失败的几种方法

目录 确认路径正确直接定位到指定目录确定目录正确&#xff0c;按如下路径修改下面是未找到相关文件正确操作 确认路径正确 &#xff0c;即d2j-dex2jar和classes.dex是否都在一个文件夹里&#xff08;大部分的情况都是路径不正确&#xff09; 直接定位到指定目录 路径正确的…

第12届蓝桥杯省赛 ---- C/C++ C组

文章目录 1. ASC2. 空间3. 卡片4. 相乘5. 路径6.时间显示7.最少砝码8. 杨辉三角形9. 左孩子右兄弟 第12届蓝桥杯省赛&#xff0c;C/C C组真题&#xff0c;第10题不是很清楚&#xff0c;题解不敢乱放&#x1f601;&#x1f601;&#x1f601; 1. ASC 额。。。。 #include <i…

Java NIO Selector选择器源码分析

文章目录 前言Selector类结构Selector抽象类AbstractSelectorSelectorImplWindowsSelectorImpl三种SelectionKey集合 前言 Java NIO&#xff08;New I/O&#xff09;的Selector选择器是一个用于多路复用&#xff08;Multiplexing&#xff09;的I/O操作的关键组件。它允许一个单…

【题目】【网络系统管理】2021年全国职业院校技能大赛模块B--样题(九)

2021年全国职业院校技能大赛 网络系统管理&#xff08;样题9&#xff09;模块B&#xff1a;Windows环境 全国职业院校技能大赛执委会.技术专家组 2021年03月 竞赛简介 请认真阅读以下指引&#xff01; 比赛共4个小时&#xff0c;你必须自行决定如何分配你的时间。 当比赛结…

java-权限修饰符、代码块

一、权限修饰符概念 权限修饰符是用来控制一个成员被访问的范围&#xff0c;可以用来修饰成员变量、方法、构造方法、内部类 二、权限修饰符的分类 举例&#xff1a; 1、private 2、空着不写 3、protected 4、public 三、权限修饰符的使用规则 实际开发中&#xff0c;一般使…

Vue2和3中的插槽区别及其简单案例

vue中的插槽是什么&#xff0c;官方解释是: Vue 实现了一套内容分发的 API&#xff0c;这套 API 的设计灵感源自 Web Components 规范草案&#xff0c;将 <slot> 元素作为承载分发内容的出口… vue2插槽和vue3插槽基本概念是一致的&#xff0c;也是匿名插槽、具名插槽、…

meshgrid如何生成网格

这里举个生成4*4的网格&#xff0c;在目标检测里常用到。 生成的坐标为4 import torch torch.arange(4) tensor([0, 1, 2, 3]) 使用meshgrid生成y、x轴坐标 import torch yv, xv torch.meshgrid([torch.arange(4),torch.arange(4)]) print(yv,xv) tensor([[0, 0, 0, 0], …

Mahalanobis距离(马氏距离)的本质

马氏距离是加权 ℓ 2 \ell_2 ℓ2​范数的特例。 马氏距离是一种基于样本分布的距离&#xff0c;加权矩阵是样本或总体协方差矩阵的逆&#xff0c;其本质为去相关数据标准化&#xff0c;通过数据变换&#xff0c;消除样本中不同特征维度间的相关性和量纲差异。

新概念英语1:Lesson 19 学习笔记

新概念英语1&#xff1a;Lesson 19 学习笔记 What’s the matter? 相当于What’s wrong?或Tell me what’s wrong.这个句型通常用来询问发生了什么事。通常用于询问对方是否有问题或烦恼。它的意思是"有什么事吗&#xff1f;"或“怎么啦”。 这个短语的语气通常…

电子台账:用控件颜色提高工作效率和数据质量

目录 1 前言 2 用页签颜色表示月度数据锁定状态 3 模板制作中定位数据源表格及其行列 3.1 鼠标移过水平过滤模板 3.2 鼠标移过垂直过滤模板 4 数据抓取过程对账页和源单元格同时染色 5 数据溯源过程&#xff0c;对企业数据源单元格染色 6 用键盘进行数据编辑后 1 前言 …

第九题:最大间隙

题目描述 给定一个序列 a1,a2,⋯ ,an。其中 a1≤a2≤⋯≤an。 相邻两个数之间的差&#xff08;后一个数减前一个数&#xff09;称为它们的间隙。 请问序列中最大的间隙值是多少&#xff1f; 输入描述 输入的第一行包含一个整数 n&#xff0c;表示序列的长度。 第二行包含…

第1个Django应用及Django的请求处理

Python学习之路系列文章目录 python面向对象之警察与匪徒火拼场景模拟python面向对像之第二次笔记Django环境搭建及测试第1个Django应用及Django的请求处理 第1个Django应用及Django的请求处理 Python学习之路系列文章目录一、PyCharm创建django项目二、创建app什么是app怎么创…