如何在Go语言中发送POST请求并获取Cookie?
我原本用Ruby编写了一段登录POST请求代码,执行后可以获取Cookie,现在需要转换成Go语言实现。我已经写了一段Go代码,但不清楚如何获取Cookie,希望得到帮助。
Ruby代码:
http = Net::HTTP.new('example.com', 443) http.use_ssl = true path = '/abc/login' data = 'data[Account][username]=myusername&data[Account][passwd]=mypassword' resp, _ = http.post(path, data)Go代码:
path := "https://example.com/abc/login" data := strings.NewReader("data[Account][username]=myusername&data[Account][passwd]=mypassword") resp, err := http.Post(path, "text/html; charset=UTF-8", data)
解决方案
首先得修正一个小细节:你的Go代码里设置的Content-Type不对。Ruby的Net::HTTP.post默认会把请求的Content-Type设为application/x-www-form-urlencoded——这是表单提交的正确类型,而你写的text/html可能会导致服务器无法正确解析登录数据,先把这一步调整过来。
接下来,获取Cookie有两种常用方式,根据你的场景选择即可:
1. 直接从响应中提取Cookie
HTTP响应的Cookie可以通过resp.Cookies()方法直接获取,它会返回一个[]*http.Cookie切片,你可以遍历这个切片拿到所有Cookie的详细信息(名称、值、域名、过期时间等)。
完整示例代码:
package main import ( "fmt" "net/http" "strings" ) func main() { path := "https://example.com/abc/login" // 修正为表单提交的正确Content-Type contentType := "application/x-www-form-urlencoded" data := strings.NewReader("data[Account][username]=myusername&data[Account][passwd]=mypassword") resp, err := http.Post(path, contentType, data) if err != nil { fmt.Printf("请求失败: %v\n", err) return } defer resp.Body.Close() // 务必记得关闭响应体,避免资源泄漏 // 获取所有Cookie并打印 cookies := resp.Cookies() for _, cookie := range cookies { fmt.Printf("Cookie名称: %s, 值: %s, 所属域名: %s\n", cookie.Name, cookie.Value, cookie.Domain) } }
2. 使用http.Client的CookieJar自动管理Cookie
如果后续还要带着这些Cookie发起其他请求(比如登录后访问需要权限的后台接口),推荐用http.Client配合http.CookieJar来自动管理Cookie——这样后续请求会自动带上之前获取的Cookie,不用手动拼接,非常方便。
示例代码:
package main import ( "fmt" "net/http" "net/http/cookiejar" "net/url" "strings" ) func main() { // 创建一个CookieJar实例,用于存储Cookie jar, err := cookiejar.New(nil) if err != nil { fmt.Printf("创建CookieJar失败: %v\n", err) return } // 初始化带CookieJar的Client,后续所有请求都会自动管理Cookie client := &http.Client{ Jar: jar, } path := "https://example.com/abc/login" contentType := "application/x-www-form-urlencoded" data := strings.NewReader("data[Account][username]=myusername&data[Account][passwd]=mypassword") resp, err := client.Post(path, contentType, data) if err != nil { fmt.Printf("登录请求失败: %v\n", err) return } defer resp.Body.Close() // 从Jar中获取当前域名下的Cookie u, err := url.Parse(path) if err != nil { fmt.Printf("解析URL失败: %v\n", err) return } cookies := jar.Cookies(u) for _, cookie := range cookies { fmt.Printf("Cookie名称: %s, 值: %s\n", cookie.Name, cookie.Value) } // 后续用这个client发起请求,会自动带上Cookie // 比如访问登录后的 dashboard 页面 // resp, err = client.Get("https://example.com/abc/dashboard") }
第一种方式适合只需要一次性获取Cookie的场景,第二种则更适合需要持续进行登录后交互的场景,根据你的需求选就行。
内容的提问来源于stack exchange,提问作者rj487
相关产品推荐
相关产品推荐

