分享
  1. 首页
  2. 文章

golang-web框架revel一个表单提交的总结

wangrudong003 · · 3134 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

这里要介绍好是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, 0644)
 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)
}
View Code

第一次进来路由指向这个页面的时候是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="50" id="txtName" name="txtName" required placeholder="学校名称">
 </div>
 <div class="form-group">
 <label for="txtLink">学校-网站地址</label>
 <input type="text" class="form-control" maxlength="200" 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="10" 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="20" 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="50" 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" .}}
View Code

最后,以上是一些知识点的个人认识和描述,有疑问或者有错误地方,欢迎来稿。


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:wangrudong003

查看原文:golang-web框架revel一个表单提交的总结

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3134 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏