在Go中重定向到页面的问题

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

Redirection to a page issue in Go

问题

我正在通过Go来提供index.html。然而,根据通过页面发送的某些参数,Go应该成功地重定向到另一个页面。在尝试执行代码时,我遇到了以下错误。

http: multiple response.WriteHeader calls

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		http.ServeFile(w, r, r.URL.Path[1:])
		fmt.Println(r.FormValue("login"))

		if r.FormValue("signup") == "signup" {
			signup(w, r)
		} else if r.FormValue("login") == "login" {
			if login(w, r) {
				if r.Method == "POST" {
					fmt.Println("I m here")
					http.Redirect(w, r, "http://localhost:8080/home.html", http.StatusSeeOther)
				}

			}

		}

	})
	var port string
	if port = os.Getenv("PORT"); len(port) == 0 {
		port = DEFAULT_PORT
	}
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

请注意,这是一个代码示例,其中包含了一个可能导致错误的部分。

英文:

I am serving index.html through go. However, depending upon certain parameters that will be send through the page, go should redirect successfully to a different page. I am getting the below error while trying to execute the code.

http: multiple response.WriteHeader calls

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

	http.ServeFile(w, r, r.URL.Path[1:])
	fmt.Println(r.FormValue("login"))

	if r.FormValue("signup") == "signup" {
		signup(w, r)
	} else if r.FormValue("login") == "login" {
		if login(w, r) {
			if r.Method == "POST" {
				fmt.Println("I m here")
				http.Redirect(w, r, "http://localhost:8080/home.html" (http://localhost:8080/home.html') , http.StatusSeeOther)
			}

		}

	}

})
var port string
if port = os.Getenv("PORT"); len(port) == 0 {
	port = DEFAULT_PORT
}
log.Fatal(http.ListenAndServe(":"+port, nil))
}

答案1

得分: 3

如评论中已经提到并在错误消息中暗示的那样,你不能两次更改响应头:

  • 当在某个地方调用http.ServeFile(w, r, r.URL.Path[1:])时,将调用w.WriteHeader(statusCode)。换句话说,将发送一个带有statusCode作为状态码的HTTP响应。
  • signuphttp.Redirect在调用w.WriteHeader之后发送HTTP响应。

因此,很难确定应该发送哪个响应。
你可能希望首先检查signuplogin,如果没有,则调用http.ServeFile

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.FormValue("login"))
    switch {
    case r.FormValue("signup") == "signup":
        signup(w, r)
    case r.FormValue("login") == "login" && login(w,r):
        if r.Method == "POST" {
            fmt.Println("I m here")
            http.Redirect(w, r, "http://localhost:8080/home.html", http.StatusSeeOther)
        }
    default:
        http.ServeFile(w, r, r.URL.Path[1:])
    }
})

更多关于为什么WriteHeader会警告你的信息来自一个可能是重复的线程

英文:

As already mentioned in the comments and implied in the error message,
you can't change the response header twice:

  • When http.ServeFile(w, r, r.URL.Path[1:]) is called in some point w.WriteHeader(statusCode) will be called. In other words, an HTTP response will be sent with statusCode as status code.
  • singup or http.Redirect sends an HTTP response after calling w.WriteHeader.

So it is very confusing which response should be sent.
You may want to check signup and login first and if none then call http.ServeFile

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.FormValue("login"))
    switch {
    case r.FormValue("signup") == "signup":
        signup(w, r)
    case r.FormValue("login") == "login" && login(w,r):
        if r.Method == "POST" {
            fmt.Println("I m here")
            http.Redirect(w, r, "http://localhost:8080/home.html" (http://localhost:8080/home.html') , http.StatusSeeOther)
    default:
        http.ServeFile(w, r, r.URL.Path[1:])
    }
})

More about why WriteHeader is warning you about this from a probably duplicated thread

huangapple
  • 本文由 发表于 2017年8月31日 15:06:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/45975293.html
匿名

发表评论

匿名网友

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

确定