go - 在 Go 中读取 cookie
问题描述
我在 Go 中部署了一个简单的 HTTP 服务器和一个简单的 HTTP 客户端。我尝试从客户端读取 cookie 值但没有成功(我收到一个空值),即使在服务器上设置了我看到的值。如何从客户端读取 cookie 值(即通过包含我收到的 cookie 来发送进一步的请求)?
服务器代码
package main
import (
"log"
"math/rand"
"net/http"
"strconv"
"strings"
"time"
)
var SERVER_PORT string = ":8080"
func setCookie(w http.ResponseWriter, username string){
cookieValue := username + ":" + (username+strconv.Itoa(rand.Intn(100000000)))
//expiration := time.Now().Add(365 * 24 * time.Hour)
expiration := time.Now().Add(20 * time.Second)
cookie := http.Cookie{Name:"SessionID", Value: cookieValue, Expires: expiration}
http.SetCookie(w, &cookie)
log.Print(cookie)
}
func sayHello(w http.ResponseWriter, r* http.Request) {
username := r.URL.Path
username = strings.TrimPrefix(username, "/")
setCookie(w,username)
message := "Hello " + username
w.Write([]byte(message))
}
func ReadCookieServer(w http.ResponseWriter, req *http.Request) {
// read cookie
var cookie,err = req.Cookie("SessionID")
if err == nil {
var cookievalue = cookie.Value
w.Write([]byte(cookievalue))
}
}
func main() {
http.HandleFunc("/", sayHello)
http.HandleFunc("/readcookie", ReadCookieServer)
if err := http.ListenAndServe(SERVER_PORT, nil); err != nil {
panic(err)
}
}
客户代码
package main
import (
"io/ioutil"
"log"
http "net/http"
)
var serverName string = "http://localhost"
var serverPort string = ":8080/"
func MakeRequest() {
var username string = "blabla"
resp, err := http.Get(serverName + serverPort + username)
if err != nil {
log.Fatalln(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
}
func Readcookie() {
resp, err := http.Get(serverName + serverPort + "readcookie")
if err != nil {
log.Fatalln(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
}
func main() {
MakeRequest()
Readcookie()
}
解决方案
如果您想从 HTTP 请求中读取 cookie,请使用该Cookies
方法。例子:
func Readcookie() {
resp, err := http.Get(serverName + serverPort + "readcookie")
if err != nil {
log.Fatalln(err)
}
for _, cookie := range resp.Cookies() {
if cookie.Name == "SessionID" {
log.Println("Cookie: ", cookie.Value)
}
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
}
为了实现更大的目标,即跨后续 HTTP 请求的会话管理,只需在 HTTP 客户端上实例化一个 cookie jar。例子:
var client *http.Client
func init() {
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
if err != nil {
panic(err)
}
client = &http.Client{Jar: jar}
}
然后将此客户端(而不是默认客户端)用于您的后续请求:
func Readcookie() {
resp, err := client.Get(serverName + serverPort + "readcookie")
if err != nil {
log.Fatalln(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
}
推荐阅读
- excel - 如何对分组表进行排序以保持较低级别完全分组
- python - 在 Python 中读取 CSV 文件,获取列(平均)
- linux - 如何通过fifo文件获取writer和reader的进程id
- c++ - NULL 和 nullptr 是否都指向同一个地址或 NULL 不指向任何地方?(我在很多地方都看到 nullptr 指向零地址)
- spring-boot - 使用 Github Action CI/CD 时构建失败
- android - Flutter 在添加 cloud_firestore 依赖时显示错误
- javascript - 如何使用 setInterval 触发一个函数,以便我可以在某个时候停止它?
- swift - 客户端崩溃后无法重新连接到 gRPC 服务器
- html - CSS flexbox 用元素填充细长但高元素右侧的可用空间,同时忽略 flex-direction 行/列轴限制
- selenium - 无法使用 selenium 登录