zoukankan      html  css  js  c++  java
  • 使用go搭建一个简单的web服务器(5)防止多次递交表单

    1.前端登陆页面

    <html>
    <head>
    <title>login</title>
    </head>
    <body>
    <form action="http://127.0.0.1:9090/login" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="hidden" name="token" value="{{.}}">
    <input type="submit" value="登陆">
    </form>
    </body>
    </html>

    2.后端处理逻辑

    package main
    
    import (
        "crypto/md5"
        "fmt"
        "html/template"
        "io"
        "log"
        "net/http"
        "strconv"
        "strings"
        "time"
    )
    
    func sayhelloname(w http.ResponseWriter, r *http.Request) {
        r.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("value:", strings.Join(v, ","))
        }
        fmt.Fprintf(w, "hello, welcome you!") //这个字符串写入到w中,用于返回给客户端。
    }
    func login(w http.ResponseWriter, r *http.Request) {
        fmt.Println("method: ", r.Method)
        if r.Method == "GET" {
            //begin这里开始计算一个时间戳用于填充到模板中的隐藏标签中
            currenttime := time.Now().Unix()
            h := md5.New()
            io.WriteString(h, strconv.FormatInt(currenttime, 10))
            token := fmt.Sprintf("%x", h.Sum(nil))
            //end
            t, _ := template.ParseFiles("login.html")
            t.Execute(w, token)
        } else {
            r.ParseForm()
            //begin利用token防止用户多次递交相同的表单
            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")))                      //输出到客户端
            //end
        }
    }
    func main() {
        http.HandleFunc("/", sayhelloname)       //设置访问的路由
        http.HandleFunc("/login", login)         //设置访问的路由
        err := http.ListenAndServe(":9090", nil) //设置监听的端口
        if err != nil {
            log.Fatal("ListenAndServe: ", err)
        }
    }

    strconv.FormatInt(i int64,base int)string
    -> 返回的i的base进制的字符串表示,base必须在2-36之间,结果中会使用小写字母a到z表示大于10的数字

    人生短,迷茫路一程又一程。 脚步重,雨雪天踟蹰也踟蹰。 滴水聚,久无成效伊人不见。 该如何,敲击敲击昼夜不停。
  • 相关阅读:
    WCF中的序列化[下篇]
    WCF中的序列化[上篇]
    SET TRANSACTION ISOLATION LEVEL 详解
    深入探讨数据仓库建模与ETL的实践技巧
    用SQL语句添加删除修改字段等操作
    WCF数据契约与序列化
    在SQL Server中使用检查约束来验证数据
    C#线程同步的几种方法[转]
    Linq的Join用法
    测试wlm代码高亮插件
  • 原文地址:https://www.cnblogs.com/DesignerA/p/11570704.html
Copyright © 2011-2022 走看看