无法写入 cookie

huangapple go评论74阅读模式
英文:

Cannot write cookie

问题

我正在尝试向网页添加两个cookie,如下所示,但它们都不起作用:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/smtp"
	"strconv"
)

type verification struct {
	Email string
}

func verify(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var user verification
	err := decoder.Decode(&user)
	if err != nil {
		panic(err)
	}
	log.Println(user.Email)

	w.WriteHeader(http.StatusCreated)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)

	min := 1000
	max := 9999
	code := strconv.Itoa(rand.Intn(max-min) + min)
	// make sure to allow less secure apps:
	// https://myaccount.google.com/lesssecureapps
	from := "myemail@gmail.com"
	pass := "mypasscode"
	to := user.Email
	body := fmt.Sprintf("Hello, your verification code is: %v", code)

	msg := "From: " + from + "\n" +
		"To: " + to + "\n" +
		"Subject: Hello there\n\n" +
		body

	err = smtp.SendMail("smtp.gmail.com:587",
		smtp.PlainAuth("Cocoon Solutions", from, pass, "smtp.gmail.com"),
		from, []string{to}, []byte(msg))

	if err != nil {
		resp["Error"] = fmt.Sprintf("%s", err)
		jsonResp, err := json.Marshal(resp)
		if err != nil {
			log.Fatalf("Error happened in JSON marshal. Err: %s", err)
		}
		w.Write(jsonResp)
		return
	}

	log.Print("verification code sent, check your email")

	cookie := http.Cookie{Name: "email", Value: "user.Email", Path: "/"} // user.Email
	http.SetCookie(w, &cookie)

	cookie2 := http.Cookie{Name: "VerificationCode", Value: "code", Path: "/"} // code
	http.SetCookie(w, &cookie2)

	resp["VerificationCode"] = code
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
}

已知在另一个代码中,它完美地工作:

package main

import (
	"fmt"
	"html/template"
	"net/http"
)

type register struct {
	Company, Name, Mobile, Whatsapp, Country, City string
}

func registration(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)                                                             //get request method
	tmpl := template.Must(template.ParseFiles(fmt.Sprintf("%v", "templates/registration.html"))) // index.html
	if r.Method == "GET" {
		//	t, _ := template.ParseFiles("login.gtpl")
		tmpl.Execute(w, nil)
	} else {
		r.ParseForm()
		fmt.Println(r.Form)
		// map[city:[Dammam] company:[Aujan] mobile:[059] name:[Hasan] whatsapp:[059]]
		// logic part of log in
		fmt.Println("company:", r.Form["company"]) // Field name at the html form
		fmt.Println("name:", r.Form["name"])
		fmt.Println("mobile:", r.Form["mobile"])
		fmt.Println("whatsapp:", r.Form["whatsapp"])
		fmt.Println("country:", r.Form["country"])
		fmt.Println("city:", r.Form["city"]) // city: [Dammam]

		//map[string]string
		content := register{
			Company:  r.PostForm.Get("company"),
			Name:     r.PostForm.Get("name"),
			Mobile:   r.PostForm.Get("mobile"),
			Whatsapp: r.PostForm.Get("whatsapp"),
			Country:  r.PostForm.Get("country"),
			City:     r.PostForm.Get("city"),
		}

		cookie := http.Cookie{Name: "logged", Value: "true", Path: "/"}
		http.SetCookie(w, &cookie)

		http.Redirect(w, r, "/index", http.StatusSeeOther) // Redirect to another url
	}
}

有什么想法吗?

英文:

I'm trying to add two cookies to the web page, as below, but none of them is working:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/smtp"
	"strconv"
)

type verification struct {
	Email string
}

func verify(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var user verification
	err := decoder.Decode(&user)
	if err != nil {
		panic(err)
	}
	log.Println(user.Email)

	w.WriteHeader(http.StatusCreated)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)

	min := 1000
	max := 9999
	code := strconv.Itoa(rand.Intn(max-min) + min)
	// make sure to allow less secure apps:
	// https://myaccount.google.com/lesssecureapps
	from := "myemail@gmail.com"
	pass := "mypasscode"
	to := user.Email
	body := fmt.Sprintf("Hello, your verification code is: %v", code)

	msg := "From: " + from + "\n" +
		"To: " + to + "\n" +
		"Subject: Hello there\n\n" +
		body

	err = smtp.SendMail("smtp.gmail.com:587",
		smtp.PlainAuth("Cocoon Solutions", from, pass, "smtp.gmail.com"),
		from, []string{to}, []byte(msg))

	if err != nil {
		resp["Error"] = fmt.Sprintf("%s", err)
		jsonResp, err := json.Marshal(resp)
		if err != nil {
			log.Fatalf("Error happened in JSON marshal. Err: %s", err)
		}
		w.Write(jsonResp)
		return
	}

	log.Print("verification code sent, check your email")

	cookie := http.Cookie{Name: "email", Value: "user.Email", Path: "/"} // user.Email
	http.SetCookie(w, &cookie)

	cookie2 := http.Cookie{Name: "VerificationCode", Value: "code", Path: "/"} // code
	http.SetCookie(w, &cookie2)

	resp["VerificationCode"] = code
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
}

Knowing that in another code, it is working perfectly:

package main

import (
	"fmt"
	"html/template"
	"net/http"
)

type register struct {
	Company, Name, Mobile, Whatsapp, Country, City string
}

func registration(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)                                                             //get request method
	tmpl := template.Must(template.ParseFiles(fmt.Sprintf("%v", "templates/registration.html"))) // index.html
	if r.Method == "GET" {
		//	t, _ := template.ParseFiles("login.gtpl")
		tmpl.Execute(w, nil)
	} else {
		r.ParseForm()
		fmt.Println(r.Form)
		// map[city:[Dammam] company:[Aujan] mobile:[059] name:[Hasan] whatsapp:[059]]
		// logic part of log in
		fmt.Println("company:", r.Form["company"]) // Field name at the html form
		fmt.Println("name:", r.Form["name"])
		fmt.Println("mobile:", r.Form["mobile"])
		fmt.Println("whatsapp:", r.Form["whatsapp"])
		fmt.Println("country:", r.Form["country"])
		fmt.Println("city:", r.Form["city"]) // city: [Dammam]

		//map[string]string
		content := register{
			Company:  r.PostForm.Get("company"),
			Name:     r.PostForm.Get("name"),
			Mobile:   r.PostForm.Get("mobile"),
			Whatsapp: r.PostForm.Get("whatsapp"),
			Country:  r.PostForm.Get("country"),
			City:     r.PostForm.Get("city"),
		}

		cookie := http.Cookie{Name: "logged", Value: "true", Path: "/"}
		http.SetCookie(w, &cookie)

		http.Redirect(w, r, "/index", http.StatusSeeOther) // Redirect to another url
	}
}

Any thoughts?

答案1

得分: 1

w.WriteHeader(http.StatusCreated)写入响应头,cookie也是响应头的一部分,所以在写入响应头之后设置cookie是不正确的。

换句话说,在调用w.WriteHeader之后对w.Header()进行的任何修改都不会出现在HTTP响应头中。http.SetCookie通过修改w.Header()来设置Cookie。


ResponseWriter.Header()

> 在调用WriteHeader(或Write)之后修改头映射不会产生任何效果,除非修改的头是尾部。


相关问题:当作为函数参数传递时修改http.ResponseWriter

英文:

w.WriteHeader(http.StatusCreated) writes the header, cookie is a header, so setting the cookie after writing the header is not-ok.

In other words, any modifications to w.Header() after w.WriteHeader was invoked, will not be present in the HTTP Response Header. http.SetCookie sets the Cookie by modifying w.Header().


ResponseWriter.Header()

> Changing the header map after a call to WriteHeader (or Write)
> has no effect unless the modified headers are trailers.


Related: Modify http.ResponseWriter when passed as a function argument

huangapple
  • 本文由 发表于 2021年10月18日 18:08:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/69614258.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定