dongou3158 2019-01-20 10:51
浏览 1564
已采纳

如何从golang中读取cookie?

I set a cookie from javascript such as :

setCookie("appointment", JSON.stringify({
                appointmentDate: selectedDay.date,
                appointmentStartMn: appointment.mnRange[0],
                appointmentId: appointment.id || 0,
                appointmentUserId: appointment.user.id || 0
          })
);

After cookie is set I want to redirect the user to a booking page :

window.location.href = "https://localhost:8080/booking/"

The setCookie function :

function setCookie(cookieName, cookieValue) {
    document.cookie = `${cookieName}=${cookieValue};secure;`;
}

I'd like to retrieve that cookie from my go backend but I can't figure out how to do this. I've read about this question since I've never used cookies before but the answers seems to tell that I don't have to do much aside from setting document.cookie.

In my browser storage I can see the cookie is indeed set as expected.

In my go backend I want to print the cookie :

r.HandleFunc("/booking/", handler.serveTemplate)

func (handler *templateHandler) serveTemplate(w http.ResponseWriter, r *http.Request) {
    c, err := r.Cookie("appointment")
    if err != nil {
        fmt.Println(err.Error())
    } else {
        fmt.Println(c.Value)
    }
}

//output http: named cookie not present

What is the specific I am missing ? I think I'm confusing local/http cookie but how to achieve the reading of client set cookies ?

UPDATE (see answer for more)

It has nothing to do with golang. My :

appointmentDate: selectedDay.date

What formatted as 2019-01-01 and - is not a valid character that can be send to the backend. It worked into my browser, but it needs to be URI encoded to be passed.

So this did the trick :

`${cookieName}=${encodeURIComponent(cookieValue)};secure;` + "path=/";`

And in go (didn't catch err here to save space) :

cookie, _ := r.Cookie("appointment")
data, _ := url.QueryUnescape(cookie.Value)
  • 写回答

1条回答 默认 最新

  • dongtiao2105 2019-01-20 12:12
    关注

    A better way would be to encode your json into base64 for example. I made a working example...

    main.go

    package main
    
    import (
        "encoding/base64"
        "encoding/json"
        "fmt"
        "io"
        "io/ioutil"
        "net/http"
    )
    
    // Contains everything about an appointment
    type Appointment struct {
        Date    string `json:"appointmentDate"`    // Contains date as string
        StartMn string `json:"appointmentStartMn"` // Our startMn ?
        ID      int    `json:"appointmentId"`      // AppointmentId
        UserID  int    `json:"appointmentUserId"`  // UserId
    }
    
    func main() {
        handler := http.NewServeMux()
    
        // Main request
        handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Printf("Requested /
    ")
    
            // set typical headers
            w.Header().Set("Content-Type", "text/html")
            w.WriteHeader(http.StatusOK)
    
            // Read file
            b, _ := ioutil.ReadFile("index.html")
            io.WriteString(w, string(b))
        })
    
        // booking request
        handler.HandleFunc("/booking/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Printf("Requested /booking/
    ")
    
            // set typical headers
            w.Header().Set("Content-Type", "text/html")
            w.WriteHeader(http.StatusOK)
    
            // Read cookie
            cookie, err := r.Cookie("appointment")
            if err != nil {
                fmt.Printf("Cant find cookie :/
    ")
                return
            }
    
            fmt.Printf("%s=%s
    ", cookie.Name, cookie.Value)
    
            // Cookie data
            data, err := base64.StdEncoding.DecodeString(cookie.Value)
            if err != nil {
                fmt.Printf("Error:", err)
            }
    
            var appointment Appointment
            er := json.Unmarshal(data, &appointment)
            if err != nil {
                fmt.Printf("Error: ", er)
            }
    
            fmt.Printf("%s, %s, %d, %d
    ", appointment.Date, appointment.StartMn, appointment.ID, appointment.UserID)
    
            // Read file
            b, _ := ioutil.ReadFile("booking.html")
            io.WriteString(w, string(b))
        })
    
        // Serve :)
        http.ListenAndServe(":8080", handler)
    }
    
    

    index.html

    <html>
        <head>
            <title>Your page</title>
        </head>
    <body>
        Setting cookie via Javascript
    
        <script type="text/javascript">
        window.onload = () => {
            function setCookie(name, value, days) {
                var expires = "";
                if (days) {
                    var date = new Date();
                    date.setTime(date.getTime() + (days*24*60*60*1000));
                    expires = "; expires=" + date.toUTCString();
                }
                document.cookie = name + "=" + btoa((value || ""))  + expires + "; path=/";
            }
    
            setCookie("appointment", JSON.stringify({
                        appointmentDate: "20-01-2019 13:06",
                        appointmentStartMn: "1-2",
                        appointmentId: 2,
                        appointmentUserId: 3
                })
            );
    
            document.location = "/booking/";
        }
        </script>
    </body>
    

    booking.html

    <html>
        <head>
            <title>Your page</title>
        </head>
    <body>
        Your booking is okay :)
    </body>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持