golang-web框架revel一个表单提交的总结
这里要介绍好是revel框架的表单post提交的列子,主要是用于入门学习,和一些知识点的讲解;
首先:
来了解一个问题那就是重复提交表单,做过form表单提交的同学都知道,如果表单提交后不做处理,那么直接在浏览器按下F5,会再次提交表单内容到服务器,这就是重复提交,当然要防止这个有多种方法,这里简单描述一种常见的:
一种是加入token失效验证,这个token其实就是一个值,验证的原理是第一次客户打开页面时候获取到一个分配的值,每次用户刷新页面的时候这个分配的值都需要变动,并且这个值在用户提交表单时候会进行验证,验证页面传递到后端程序保存的值是否一致,如果提交表单成功后,这个值会失效或者来说被清空。
其次:上代码+分析
package controllers import "github.com/revel/revel"
import "fmt" //import "io/ioutil"
import "encoding/json"
import "os"
import "io"
import "time"
import "net/http" type Concate struct {
Name string
Link string
Concat string
Tel string
Email string
} func WriteFileAppend(filename string, data []byte) error { fl, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE, )
if err != nil {
return err
}
defer fl.Close()
n, err := fl.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
return err
} func (c App) Add() revel.Result { method := c.Request.Method
fmt.Printf(method)
ck_name := "add_token"
if method == "POST" { name := c.Params.Get("txtName")
link := c.Params.Get("txtLink")
concat := c.Params.Get("txtHeader")
tel := c.Params.Get("txtTel")
email := c.Params.Get("txtEmail") token := c.Params.Get("add_token") fmt.Printf("学校加入参数:name=%v;link=%v;concat=%v;tel=%v;email=%v;token=%V", name, link, concat, tel, email, token) c.Validation.Required(token).Message("token验证失败,请重新打开页面") c.Validation.Required(name).Message("学校名称,必须填写")
c.Validation.Required(concat).Message("申请人名,必须填写")
c.Validation.Required(tel).Message("联系电话,必须填写")
c.Validation.Required(email).Message("联系邮箱,必须填写") if c.Validation.HasErrors() {
// 在flash上下文中保存验证错误并重定向
c.Validation.Keep()
c.FlashParams()
return c.Render()
} result := "加入园子-失败"
ck_Token, ck_err := c.Request.Cookie(ck_name)
if ck_err != nil {
return c.Render(result)
} if ck_Token.Value != token {
return c.Render(result)
} concate := Concate{Name: name, Link: link, Concat: concat, Tel: tel, Email: email}
bb, err := json.Marshal(concate)
if err != nil {
return c.Render(result)
}
bstr := string(bb) + ","
bbNew := []byte(bstr)
err = WriteFileAppend(`./WiKiApp/public/js/add.json`, bbNew)
if err == nil {
result = " 加入园子-成功,稍后会有邮件或客服人员联系您"
}
return c.Render(result)
} //创建token,防止重复提交
token := time.Now().Format("2006-01-02 15:04:05") ck := http.Cookie{Name: ck_name, Value: token}
c.SetCookie(&ck)
return c.Render(token)
}
第一次进来路由指向这个页面的时候是get请求,此时使用cookie保存一下生成的token,revel框架是mvc模式,可以通过c.Render(token)把参数输出到页面上,在使用模板直接绑定到hidden元素上面
<input type="hidden" name="add_token" value="{{.token}}"/>这里把token输出到了影藏域里面,
下面就是填写表单内容,再执行保存提交按钮,post到后台的地址,这里的代码知识点有
1.c.Request.Method:获取请求的http方式;
2.c.Params.Get("txtName"):获取页面元素name为txtName名字的参数值;
3.fmt.Printf("%v","我爱祖国"):这里的print就是打印信息在后台,%v是占位符,类似于C#{0}效果;
4.c.Validation.Required(token).Message("token验证失败,请重新打开页面"):c.Validation.Required是revel框架封装的验证方法,Message("xxxx")是不符合验证格式了,就返回的提示信息;
5.c.FlashParams():revel框架的验证错误信息是一次性的,类似于.net mvc中的tempdata效果,只能被读取一次;
6.ck_Token, ck_err := c.Request.Cookie(ck_name):Request.Cookie是获取对应名称的cookie信息,这里看到的:=是go语言的语法,此语法的作用很大,具体请去了解go基础;
7.bbNew := []byte(bstr):这里[]byte()直接吧字符串信息转化成了byte[]看起来是不是很方便
8.WriteFileAppend:是自定义的记录文本信息的方法,里面最重要的是defer fl.Close(),这个defer意思就是等待方法执行完后,在调用这个close释放资源,这里有点像finally的感觉
再发下html模板代码
{{set . "title" "搜-学校-加入圈子"}}
{{template "header.html" .}} <form action="/app/add" method="post" style="margin-bottom:20px">
<div class="form-group">
<label for="txtName">学校-名称(<font style="color:#337ab7">必填</font>)</label>
<input type="text" class="form-control" maxlength="" id="txtName" name="txtName" required placeholder="学校名称">
</div>
<div class="form-group">
<label for="txtLink">学校-网站地址</label>
<input type="text" class="form-control" maxlength="" id="txtLink" name="txtLink" placeholder="http://xxx">
</div>
<div class="form-group">
<label for="txtHeader">学校-申请人(<font style="color:#337ab7">必填</font>)</label>
<input type="text" class="form-control" maxlength="" id="txtHeader" name="txtHeader" required placeholder="申请人名字">
</div>
<div class="form-group">
<label for="txtTel">申请-电话(<font style="color:#337ab7">必填</font>)</label>
<input type="text" class="form-control" maxlength="" id="txtTel" name="txtTel" required placeholder="申请人联系电话号码">
</div>
<div class="form-group">
<label for="txtEmail">申请-邮箱(<font style="color:#337ab7">必填</font>)</label>
<input type="Email" class="form-control" maxlength="" id="txtEmail" name="txtEmail" required placeholder="申请人邮箱如:8123@qq.com">
</div>
<!--<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" id="exampleInputFile">
<p class="help-block">Example block-level help text here.</p>
</div>-->
<!--<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>-->
<button type="submit" class="btn btn-success">保 存</button>
<input type="hidden" name="add_token" value="{{.token}}"/>
<span>{{.result}}</span>
</form>
<div class="container">
<div class="row">
<div class="span6">
{{template "flash.html" .}}
</div>
</div>
</div>
{{template "footer.html" .}}
最后,以上是一些知识点的个人认识和描述,有疑问或者有错误地方,欢迎来稿。
golang-web框架revel一个表单提交的总结的更多相关文章
- Maven web项目(简单的表单提交) 搭建(eclipse)
我们将会搭建一个,基于Maven管理的,具有简单的表单提交功能的web项目,使用DAO--service--WEB三层结构,服务器使用Tomcat 1 项目基本结构的搭建 左上角File---> ...
- 【HTML相关】iframe+javascript实现一个表单提交后多个处理文件按序处理
最近在弄一个网页的问题,总结如下. [问题描述] 页面中包括以下几个部分:1)表单form,供用户输入图片文件:2)iframe1,显示a.php文件的内容,a.php接收客户端图片并保存,后台程序处 ...
- Js定义一个表单并提交
Js定义一个表单 var form = $("<form>"); //定义一个form表单 form.attr('style', 'display:none'); // ...
- 2017-01-11小程序form表单提交
小程序form表单提交 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了微信端,用小程序固定的格式前前端进行布局.事件触发和数据的输送和读取,服务器端可以用任何后端语言写,但 ...
- 微信小程序 PHP后端form表单提交实例详解
微信小程序php后端form表单 https://www.cnblogs.com/tdalcn/p/7092716.html 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了 ...
- <input type="image">表单提交2次 重复插入数据问题
写一个表单提交用到图片:两种代码. <input type="image" src="xxx.gif"onclick="return dosub ...
- 使用axios模拟表单提交
1.需求背景 最近在实验室写一个Spring前后端分离的项目,项目中使用Spring Security组件实现系统的认证和授权,当Security的认证模式设置为FormLogin时(如下代码),前端 ...
- 第6章—渲染web视图—SpringMVC+Thymeleaf 处理表单提交
SpringMVC+Thymeleaf 处理表单提交 thymleaf处理表单提交的方式和jsp有些类似,也有点不同之处,这里操作一个小Demo,并说明: 1.demo的结构图如下所示: pom.xm ...
- DWZ框架Ajax无刷新表单提交处理流程
DWZ框架Ajax无刷新表单提交处理流程是: 1. ajax表单提交给服务器 2. 服务器返回一个固定格式json结构 3. js会调函数根据这个json数据做相应 ...
随机推荐
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(72)-微信公众平台开发-消息处理
系列目录 前言 Senparc.Weixin.MP SDK提供了MessageHandler消息处理类 在作者的Wiki中也详细说明了如何定义这个类,下面我们来演示,消息的回复,及效果 了解Messa ...
- JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题
1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...
- Ajax实现原理,代码封装
都知道实现页面的异步操作需要使用Ajax,那么Ajax到是怎么实现异步操作的呢? 首先需要认识一个对象 --> XMLHttpRequest 对象 --> Ajax的核心.它有许多的属性和 ...
- ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...
- enote笔记法使用范例(2)——指针(1)智能指针
要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...
- SymmetricDS 快速和灵活的数据库复制
开始谈谈开源的SymmetricDS,谈谈实际使用中,遇到的一些问题和解决办法.持续更新: SymmetricDS 快速和灵活的数据库复制 实际使用 和 埋过的坑 (一)知识篇 SymmetricDS ...
- Linux网络属性配置
目录 IP地址分类 如何将Linux主机接入到网络中 网络接口的命名方式 ifcfg系列命令 如何配置主机名 如何配置DNS服务器指向 iproute2系列命令 Linux管理网络服务 永久生效配置路 ...
- [学习笔记]JavaScript之函数式编程
欢迎指导与讨论:) 前言 函数式编程能使我们的代码结构变得简洁,让代码更接近于自然语言,易于理解. 一.减少不必要的函数嵌套代码 (1)当存在函数嵌套时,若内层函数的参数与外层函数的参数一致时,可以这 ...
- hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()的用法
javascript中有原型这么一个概念,任何一个构造函数都有它对应的原型(prototype),我们可以给这个原型赋予一些我们想要的属性,像下面这样: function Gadget(name, c ...
- 我的MYSQL学习心得(二) 数据类型宽度
我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...