一、基础原理理解
- 浏览器访问
GET /login,后端返回登录页面 login.html,一次请求对应一次响应。 - 在表单填入账号密码,点击登录按钮,浏览器发起第二次请求。
- form 表单属性说明
action="/login":表单提交后请求的后端接口地址method="post":提交请求方式为 POST
- ⚠️大坑:表单用 POST 提交,如果后端只写了
r.GET("/login")没有写 POST 路由,访问直接404。 - 表单提交按钮:
<input type="button">只是普通按钮,不会自动提交表单 ,必须改为<input type="submit">
前端页面上请求发到哪里,完全由 form 标签的
action属性决定。
二、初始错误版代码(踩坑示例)
main.go
Go
package main
import(
"github.com/gin-gonic/gin"
"net/http"
)
//获取form表单提交的参数
func main() {
r := gin.Default()
r.LoadHTMLFiles("./login.html")
r.GET("/login", func(c *gin.Context) {
c.HTML(http.StatusOK, "login.html", nil)
})
r.Run(":9090")
}
login.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form action="/login" method="post">
<label for="username">username:</label>
<input type="text" name="username" id="username">
<label for="password">password:</label>
<input type="password" name="password" id="password">
<!-- type="button" 无法提交表单,bug点 -->
<input type="button" value="登录">
</form>
</body>
</html>
问题:缺少 POST 路由;按钮不能提交表单,点击登录无任何反应。
三、Gin 接收 Form 表单参数的 3 种方法
前提:添加 POST 路由
r.POST("/login", 回调函数)
方法 1:c.PostForm ()
功能:获取表单参数;取不到参数返回空字符串 ""
Go
r.POST("/login", func(c *gin.Context) {
// 获取表单里的用户名和密码
username := c.PostForm("username")
password := c.PostForm("password")
c.String(http.StatusOK, "提交成功!username=%s, password=%s", username, password)
})
方法 2:c.DefaultPostForm ()
功能:获取表单参数;取不到参数,返回我们设置好的默认值
Go
r.POST("/login", func(c *gin.Context) {
username := c.DefaultPostForm("username", "somebody")
password := c.DefaultPostForm("password", "***")
println("用户名:", username)
println("密码:", password)
c.String(http.StatusOK, "提交成功!username=%s, password=%s", username, password)
})
方法 3:c.GetPostForm ()(推荐,可判断参数是否存在)
返回两个值:(参数值,是否成功获取到参数 bool) 可以区分:用户没传参数 / 用户传了空字符串
Go
r.POST("/login", func(c *gin.Context) {
username, ok := c.GetPostForm("username")
if !ok {
username = "sb"
}
password, ok := c.GetPostForm("password")
if !ok {
password = "***"
}
c.String(http.StatusOK, "提交成功!username=%s, password=%s", username, password)
})
四、完整可运行正确代码
Go
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.LoadHTMLFiles("./login.html")
// GET路由:展示登录页面
r.GET("/login", func(c *gin.Context) {
c.HTML(http.StatusOK, "login.html", nil)
})
// POST路由:接收表单提交的数据
r.POST("/login", func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
fmt.Println("用户名:", username, "密码:", password)
c.String(http.StatusOK, "提交成功!username=%s, password=%s", username, password)
})
r.Run(":9090")
}
五、三个 API 对比总结表
表格
| 方法 | 返回值 | 获取不到参数的结果 | 使用场景 |
|---|---|---|---|
| c.PostForm("key") | value | 返回空字符串 "" | 参数必填,不需要默认值 |
| c.DefaultPostForm ("key","默认值") | value | 返回设置的默认值 | 可选参数,兜底填充默认值 |
| c.GetPostForm("key") | (value,ok) | ok=false | 需要校验参数是否传递,推荐用于登录校验 |
六、复习易错点清单
- GET 路由只负责展示页面,POST 路由负责接收表单提交数据,两条路由相互独立。
- form 标签
method="post",后端必须使用r.POST(),不能用 GET,否则 404。 - input 标签必须带
name="xxx"属性!后端获取参数靠 name,不是 id。 - 提交按钮必须写
type="submit",普通 button 不会触发表单提交。 - 一次请求对应一次响应;不同请求方式(GET/POST)属于完全不同的请求。