英文:
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。
> 在调用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()
.
> 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论