在Go语言中使用net_http包发送HTTP请求时,获取服务端返回的响应Cookie是很多业务场景的必备需求,比如模拟登录、保持会话状态等。掌握正确的获取方式能避免很多不必要的调试问题。

基础获取响应Cookie的方法
Go的http.Response结构体提供了专门的Header和Cookies方法来获取响应中的Cookie信息,最常用的是Cookies方法,它会自动解析响应头中的Set-Cookie字段并返回[]*http.Cookie切片。
下面是一个最简单的获取示例:
package main
import (
"fmt"
"net/http"
)
func main() {
// 发送GET请求
resp, err := http.Get("http://127.0.0.1:8080/login")
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
// 获取所有响应Cookie
cookies := resp.Cookies()
for _, cookie := range cookies {
fmt.Printf("Cookie名称: %s, 值: %s, 过期时间: %vn", cookie.Name, cookie.Value, cookie.Expires)
}
}
手动解析Set-Cookie响应头
如果Cookies方法无法满足需求,比如需要获取原始的Set-Cookie头内容,也可以通过resp.Header直接获取:
package main
import (
"fmt"
"net/http"
"strings"
)
func main() {
resp, err := http.Get("http://127.0.0.1:8080/login")
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
// 获取所有Set-Cookie头
setCookieHeaders := resp.Header["Set-Cookie"]
for _, header := range setCookieHeaders {
fmt.Println("原始Set-Cookie内容:", header)
// 可以手动分割解析,比如按分号分割获取各个属性
parts := strings.Split(header, ";")
fmt.Println("分割后的属性:", parts)
}
}
常见错误场景与解决
错误1:忽略响应体关闭导致Cookie获取异常
很多开发者会忘记调用resp.Body.Close(),虽然短期可能不会报错,但长期运行会导致资源泄漏,甚至影响后续请求的Cookie处理。正确做法是在请求成功后立即用defer关闭响应体。
错误2:自定义Client时未正确处理重定向
如果使用了自定义的http.Client并且修改了CheckRedirect逻辑,可能会导致重定向过程中Cookie丢失。默认情况下,Go的Client会在重定向时自动携带之前收到的Cookie,自定义重定向逻辑时需要注意保留这个行为。
package main
import (
"fmt"
"net/http"
)
func main() {
client := &http.Client{
// 自定义重定向策略,最多允许3次重定向
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 3 {
return fmt.Errorf("重定向次数过多")
}
// 保留原有的Cookie传递逻辑
return nil
},
}
resp, err := client.Get("http://127.0.0.1:8080/redirect")
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
cookies := resp.Cookies()
fmt.Printf("获取到%d个Cookien", len(cookies))
}
Cookie属性与后续请求传递
获取到的http.Cookie结构体包含了Cookie的所有属性,比如Domain、Path、MaxAge、Secure、HttpOnly等,这些属性会影响Cookie的生效范围。
如果需要在后续请求中携带获取到的Cookie,可以将Cookie添加到新请求的Header中,或者直接使用client.Jar来管理Cookie:
package main
import (
"fmt"
"net/http"
"net/http/cookiejar"
)
func main() {
// 创建带CookieJar的Client
jar, err := cookiejar.New(nil)
if err != nil {
fmt.Println("创建CookieJar失败:", err)
return
}
client := &http.Client{
Jar: jar,
}
// 第一次请求,获取Cookie
resp1, err := client.Get("http://127.0.0.1:8080/login")
if err != nil {
fmt.Println("第一次请求失败:", err)
return
}
defer resp1.Body.Close()
fmt.Printf("第一次请求获取到%d个Cookien", len(resp1.Cookies()))
// 第二次请求,会自动携带之前的Cookie
resp2, err := client.Get("http://127.0.0.1:8080/profile")
if err != nil {
fmt.Println("第二次请求失败:", err)
return
}
defer resp2.Body.Close()
fmt.Println("第二次请求成功,Cookie已自动携带")
}
注意事项
- 如果服务端返回的
Set-Cookie头格式不符合规范,Cookies方法可能无法正确解析,此时需要手动解析Set-Cookie头内容。 - Cookie的
Domain和Path属性会限制Cookie的发送范围,只有匹配的请求才会携带对应的Cookie。 - 使用
cookiejar管理Cookie时,需要注意其默认不会持久化Cookie,程序重启后Cookie会丢失,需要持久化的话需要自定义Jar的实现。
GoHTTP_ClientCookienet_http修改时间:2026-07-04 17:45:28