

新闻资讯
技术学院r.ParseForm()必须在读取r.PostForm前调用,因Go默认不自动解析表单;需显式触发,否则导致空值或panic,并影响Content-Type区分与参数合并。
r.ParseForm() 必须在读取 r.PostForm 前调用不调用 r.ParseForm() 就直接访问 r.PostForm 或 r.FormValue("username"),会导致空值或 panic —— 因为 Go 的 http.Request 默认不会自动解析表单数据,必须显式触发解析。它还会根据 Content-Type 自动区分 application/x-www-form-urlencoded 和 multipart/form-data(如含文件上传),但前提是请求头正确且已调用该函数。
实操建议:
if err := r.ParseForm(); err != nil { ... }
fetch 提交 JSON,后端不能依赖 r.FormValue,而要用 json.Decoder 读取 r.Body
r.ParseForm() 会把 query string 和 body 表单合并进 r.Form,注意同名参数覆盖顺序(body 优先)database/sql 插入用户数据时如何安全防 SQL 注入拼接字符串构造 SQL(如 "INSERT INTO users VALUES ('" + username + "')" )在 Go 中一样危险,且无法利用数据库连接池预编译优化。Go 的 database/sql 原生支持参数化查询,Exec 和 Query 方法都接受 ... 可变参数传入值,底层由驱动完成绑定。
实操建议:
?, $1, $2 占位符(取决于驱动:MySQL 用 ?,PostgreSQL 用 $1)golang.org/x/crypto/bcrypt 先哈希:hashed, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
result.RowsAffected() 确认是否成功写入,而非只看 error 是否为 nilGo 的 http.ServeMux 是严格匹配路径和方法的:注册了 http.HandleFunc("/register", handler),但前端 form 的 action 写成 /register/(多斜杠)或用 GET 提交,就会 404 或 405。另外,如果 handler 只处理 POST,却没对其他方法返回明确提示,浏览器可能缓存旧请求方式。
实操建议:
method="POST" 必须与 handler 中判断的 r.Method == "POST" 一致"/register",前端 action 也保持完全一致,避免尾部斜杠差异if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}net/http 做注册接口时,不应该在 handler 里直接操作全局 *sql.DB
全局 *sql.DB 本身是并发安全的,可以被多个 goroutine 共享,但问题出在「直接裸用」容易导致连接泄漏或事务失控。比如忘记调用 rows.Close()、在 handler 中开启事务却不统一 commit/rollback、或错误地复用 sql.Tx 跨请求。
实操建议:
*sql.DB 作为依赖注入 handler,例如闭包封装:func makeRegisterHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { ... }
}defer tx.Rollback() 并在成功后显式 tx.Commit()
sql.Rows 或未关闭的 sql.Tx,它们会阻塞连接池r.ParseForm() 的调用位置和 bcrypt 的哈希步骤,这两处最容易被跳过或写反。