在Go语言Web开发中,HTTP Cookie是常用的状态维持手段,无论是用户登录态保持还是个性化配置存储,都离不开Cookie的正确配置。如果使用不当,很容易出现浏览器不存储Cookie、跨域场景下Cookie丢失、安全风险升高等问题,因此需要掌握基于net_http标准库设置Cookie的正确方法。

Cookie基础结构
Go语言中Cookie由http.Cookie结构体表示,核心字段包含名称、值、过期时间、作用路径、域名、安全属性等,各个字段直接对应HTTP响应头中Set-Cookie的对应参数,配置时需要和浏览器Cookie规范对齐。
基础设置流程
设置Cookie的核心逻辑是构造http.Cookie实例,再通过http.SetCookie方法写入响应头,以下是最小化的设置示例:
package main
import (
"net/http"
"time"
)
func setCookieHandler(w http.ResponseWriter, r *http.Request) {
// 构造Cookie实例
cookie := &http.Cookie{
Name: "user_token", // Cookie名称
Value: "abc123xyz", // Cookie值
Path: "/", // 作用路径,全站生效
MaxAge: 3600, // 最大存活时间,单位秒,1小时
HttpOnly: true, // 禁止JS读取,提升安全性
}
// 写入响应头
http.SetCookie(w, cookie)
w.Write([]byte("Cookie设置完成"))
}
func main() {
http.HandleFunc("/set-cookie", setCookieHandler)
http.ListenAndServe(":8080", nil)
}关键属性说明
- MaxAge与Expires:MaxAge是相对当前时间的存活秒数,优先级高于Expires;Expires是绝对过期时间,设置时需注意时区问题,推荐使用MaxAge。
- HttpOnly:设置为true时,浏览器端JavaScript无法通过document.cookie读取该Cookie,能有效降低XSS攻击盗取Cookie的风险。
- Secure:设置为true时,Cookie仅在HTTPS连接中传输,避免明文HTTP场景下Cookie被窃听,生产环境建议开启。
- SameSite:可选值有Strict、Lax、None,用于控制跨站请求时是否携带Cookie,Strict限制最严格,None需要配合Secure使用,能解决跨域Cookie携带问题。
- Domain与Path:Domain指定Cookie生效的域名,默认是当前请求的域名;Path指定生效的路径,默认是设置Cookie的路径,配置错误会导致Cookie无法在预期页面生效。
获取与删除Cookie
获取Cookie使用r.Cookie方法,删除Cookie只需设置MaxAge为-1,同时保证Name、Path、Domain等属性和设置时一致:
package main
import (
"fmt"
"net/http"
)
func getCookieHandler(w http.ResponseWriter, r *http.Request) {
// 获取指定名称的Cookie
cookie, err := r.Cookie("user_token")
if err != nil {
fmt.Fprintf(w, "未找到Cookie: %v", err)
return
}
fmt.Fprintf(w, "Cookie值为: %s", cookie.Value)
}
func deleteCookieHandler(w http.ResponseWriter, r *http.Request) {
// 删除Cookie,MaxAge设为-1
cookie := &http.Cookie{
Name: "user_token",
Value: "",
Path: "/",
MaxAge: -1,
}
http.SetCookie(w, cookie)
w.Write([]byte("Cookie已删除"))
}
func main() {
http.HandleFunc("/get-cookie", getCookieHandler)
http.HandleFunc("/delete-cookie", deleteCookieHandler)
http.ListenAndServe(":8080", nil)
}常见问题排查
如果设置的Cookie不生效,可以先检查响应头中是否存在Set-Cookie字段,再确认Domain、Path是否匹配当前请求,跨域场景下还需要检查SameSite和Secure的配置,以及前端请求的credentials属性是否设置为include。如果是本地开发使用localhost,Domain可以留空,避免域名匹配问题。