请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

goweb-表单

[复制链接]
查看: 79|回复: 0

2万

主题

3万

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81333
发表于 2020-1-14 15:06 | 显示全部楼层 |阅读模式
表单

简单的处置惩罚一个登陆界面
  1. package mainimport (    "fmt"    "html/template"    "log"    "net/http"    "strings")func sayhelloName(w http.ResponseWriter, r *http.Request) {    r.ParseForm()       //分解url转达的参数,对于POST则分解响应包的主体(request body)    //留意:假如没有挪用ParseForm方式,下面没法获得表单的数据    fmt.Println(r.Form) //这些信息是输出到办事器真个打印信息    fmt.Println("path", r.URL.Path)    fmt.Println("scheme", r.URL.Scheme)    fmt.Println(r.Form["url_long"])    for k, v := range r.Form {        fmt.Println("key:", k)        fmt.Println("val:", strings.Join(v, ""))    }    fmt.Fprintf(w, "Hello astaxie!") //这个写入到w的是输出到客户真个}func login(w http.ResponseWriter, r *http.Request) {    fmt.Println("method:", r.Method) //获得请求的方式    if r.Method == "GET" {        t, _ := template.ParseFiles("login.gtpl")        log.Println(t.Execute(w, nil))    } else {        //请求的是登录数据,那末尝试登录的逻辑判定        fmt.Println("username:", r.Form["username"])        fmt.Println("password:", r.Form["password"])    }}func main() {    http.HandleFunc("/", sayhelloName)       //设备拜候的路由    http.HandleFunc("/login", login)         //设备拜候的路由    err := http.ListenAndServe(":9090", nil) //设备监听的端口    if err != nil {        log.Fatal("ListenAndServe: ", err)    }}
复制代码
request.Form是一个url.Values典范,里面存储的是对应的类似key=value的信息,下面展现了可以对form数据举行的一些利用:
  1. v := url.Values{}v.Set("name", "Ava")v.Add("friend", "Jess")v.Add("friend", "Sarah")v.Add("friend", "Zoe")// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"fmt.Println(v.Get("name"))fmt.Println(v.Get("friend"))fmt.Println(v["friend"])
复制代码
Request自己也供给了FormValue()函数来获得用户提交的参数。如r.Form["username"]也可写成r.FormValue("username")。挪用r.FormValue时会自动挪用r.ParseForm,所以不必提早挪用。r.FormValue只会返回同名参数中的第一个,若参数不存在则返回空字符串。
办事端表单考证

这一部分讲了考证数字,中文,名字,号码等很多需要考证的工具,重要有:经过正则考证,经过逻辑结构考证并挪用关连的包
防御跨站剧本

现在的网站包含大量的静态内容以进步用户体验,比过去要复杂很多。所谓静态内容,就是按照用户情况和需要,Web利用步伐可以大要输出响应的内容。静态站点会遭到一种名为“跨站剧本进犯”(Cross Site Scripting, 平安专家们凡是将其缩写成 XSS)的威胁,而静态站点则完全不受其影响。
进犯者凡是会在有毛病的步伐中插入JavaScript、VBScript、 ActiveX或Flash以拐骗用户。一旦得手,他们可以盗取用户帐户信息,点窜用户设备,盗取/净化cookie和植入恶意广告等。
对XSS最好的防护应当团结以下两种方式:一是考证全数输入数据,有用检测进犯(这个我们前面小节已经有过先容);另一个是对全数输出数据举行得当的处置惩罚,以避免任何已乐成注入的剧本在欣赏器端运转。
重要经过转义来实现这个,用到text/template和html/template
避免屡次递交表单

不晓得你能否已经看到过一个论坛大要博客,在一个帖子大要文章后背出现多条反复的记录,这些大大都是由于用户反复递交了留言的表单引发的。由于各种原因原由,用户经常会反复递交表单。凡是这只是鼠标的误利用,如双击了递交按钮,也大如果为了编辑大要再次核对填写过的信息,点击了欣赏器的退却按钮,然后又再次点击了递交按钮而不是欣赏器的进步按钮。固然,也大如果故意的——比如,在某项在线观察大要博彩活动中反复投票。那我们怎样有用的避免用户屡次递交类似的表单呢?
治理计划是在表单中增加一个带有唯一值的潜伏字段。在考证表单时,先检查带有该唯一值的表单能否已经递交过了。假如是,拒绝再次递交;假如不是,则处置惩罚表单举行逻辑处置惩罚。此外,假如是采取了Ajax形式递交表单的话,当表单递交后,经过javascript来禁用表单的递交按钮。
  1. func login(w http.ResponseWriter, r *http.Request) {    fmt.Println("method:", r.Method) //获得请求的方式    if r.Method == "GET" {        crutime := time.Now().Unix()        h := md5.New()        io.WriteString(h, strconv.FormatInt(crutime, 10))        token := fmt.Sprintf("%x", h.Sum(nil))        t, _ := template.ParseFiles("login.gtpl")        t.Execute(w, token)    } else {        //请求的是登陆数据,那末尝试登陆的逻辑判定        r.ParseForm()        token := r.Form.Get("token")        if token != "" {            //考证token的正当性        } else {            //不存在token报错        }        fmt.Println("username length:", len(r.Form["username"][0]))        fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) //输出到办事器端        fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password")))        template.HTMLEscape(w, []byte(r.Form.Get("username"))) //输出到客户端    }}
复制代码
利用唯一性来判定,但并不能避免恶意的进犯
处置惩罚文件上传

你想处置惩罚一个由用户上传的文件,比如你正在建立一个类似Instagram的网站,你需要存储用户拍摄的照片。这类需求该怎样实现呢?
要使表单可以大要上传文件,首先第一步就是要增加form的enctype属性,enctype属性有以下三种情况:

  • application/x-www-form-urlencoded 表现在发送前编码全数字符(默许)
  • multipart/form-data 差池字符编码。在利用包含文件上传控件的表单时,必须利用该值。
  • text/plain 空格转换为 "+" 加号,但差池出格字符编码。
上传文件重要三步处置惩罚:
  1. 表单中增加enctype="multipart/form-data"办事端挪用r.ParseMultipartForm,把上传的文件存储在内存和姑且文件中利用r.FormFile获得文件句柄,然后对文件举行存储等处置惩罚
复制代码
Go支持模拟客户端表单功用支持文件上传,具体用法请看以下示例:
  1. package mainimport (    "bytes"    "fmt"    "io"    "io/ioutil"    "mime/multipart"    "net/http"    "os")func postFile(filename string, targetUrl string) error {    bodyBuf := &bytes.Buffer{}    bodyWriter := multipart.NewWriter(bodyBuf)    //关键的一步利用    fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename)    if err != nil {        fmt.Println("error writing to buffer")        return err    }    //翻开文件句柄利用    fh, err := os.Open(filename)    if err != nil {        fmt.Println("error opening file")        return err    }    defer fh.Close()        //iocopy    _, err = io.Copy(fileWriter, fh)    if err != nil {        return err    }    contentType := bodyWriter.FormDataContentType()    bodyWriter.Close()    resp, err := http.Post(targetUrl, contentType, bodyBuf)    if err != nil {        return err    }    defer resp.Body.Close()    resp_body, err := ioutil.ReadAll(resp.Body)    if err != nil {        return err    }    fmt.Println(resp.Status)    fmt.Println(string(resp_body))    return nil}// sample usagefunc main() {    target_url := "http://localhost:9090/upload"    filename := "./astaxie.pdf"    postFile(filename, target_url)}
复制代码
这一章里面我们进修了Go若何处置惩罚表单信息,我们经过用户登录、上传文件的例子展现了Go处置惩罚form表单信息及上传文件的本事。可是在处置惩罚表单进程中我们需要考证用户输入的信息,考虑到网站平安的垂危性,数据过滤就显得相当垂危了,是以后背的章节中专门写了一个小节来说解了不同方面的数据过滤,顺带讲一下Go对字符串的正则处置惩罚。
客户端和办事器端是怎样举行数据上的交互,客户端将数据转达给办事器系统,办事器担任数据又把处置惩罚成果反应给客户端。
链接

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 妈妈网-中国妈妈第一,是怀孕、育儿、健康等知识交流传播首选平台 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表