Golang中如何解决简单的重定向问题

Golang中如何解决简单的重定向问题 大家好

以下代码中我的错误在哪里? POST http://localhost:5050/main?user_id=10&pw=abcd https://play.golang.org/p/ZKTe54RQ6wQ

任何帮助都将不胜感激, 提前感谢。

7 回复

感谢Johan,你解决了我的问题,真是帮了大忙!😊

更多关于Golang中如何解决简单的重定向问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


很高兴能帮到你

go http.ListenAndServe(":5050",http.HandlerFunc(redirect))

应该是

http.ListenAndServe(":5050", nil)

nil 表示使用默认的多路复用器。如果你将其作为一个独立的 goroutine 启动,程序会继续执行并退出。但你希望 ListenAndServe 能够“无限期”运行并监听新的连接。

感谢,Johan,实际上我想将HTTP重定向到HTTPS。这里我们假设8080端口是HTTPS:

go http.ListenAndServe(":5050",http.HandlerFunc(redirect))
err:= http.ListenAndServeTLS(":8080","cert.pem","key.pem",nil)
if err != nil {
fmt.Println("main.go", 23, err)
}

抱歉。我读得有点太快了。你可以这样做:在一台物理服务器或VPS上运行多个Web服务器,以拥有两个不同的服务器复用器,或者对HTTPS使用默认的,仅为HTTP创建一个新的复用器,其中只包含一个重定向方法。

package main

import (
	"io"
	"net/http"
)

func index1(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Hello from server 1")
}

func index2(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, "Hello from server 2")
}

func main() {

	mux := http.NewServeMux()
	mux.HandleFunc("/", index1)

	http.HandleFunc("/", index2)

	go http.ListenAndServe("localhost:8001", mux)

	http.ListenAndServe("localhost:8002", nil)
}

有几个需要修正的错误。

indexHandler 函数中,重定向应使用 http.StatusSeeOther 而非 http.StatusFound 来表示临时重定向。

func indexHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "/main?user_id=10&pw=abcd", http.StatusSeeOther)
}

mainHandler 函数中,获取表单值的方式不正确。应使用 r.FormValue 而非 r.URL.Query().Get 来获取表单值。

func mainHandler(w http.ResponseWriter, r *http.Request) {
	userID := r.FormValue("user_id")
	password := r.FormValue("pw")
	fmt.Printf("user_id: %s, pw: %s\n", userID, password)
}

进行这些更改后,重定向应该能正确工作。

这里有一个专业建议:如果你想深入了解你的URL是如何重定向的,可以查看这个工具 https://redirectchecker.com/。你可以设置你的登录密码并检查你的应用程序的重定向效果。

在Go中处理重定向时,常见的问题是http.Client默认会自动跟随重定向。根据你的代码,问题可能出现在客户端自动处理了重定向,导致你无法捕获中间状态。

以下是修改后的示例,通过自定义CheckRedirect函数来控制重定向行为:

package main

import (
    "fmt"
    "io"
    "net/http"
    "net/http/httputil"
)

func main() {
    client := &http.Client{
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            // 返回此错误可阻止自动重定向
            return http.ErrUseLastResponse
        },
    }

    req, err := http.NewRequest("POST", "http://localhost:5050/main?user_id=10&pw=abcd", nil)
    if err != nil {
        panic(err)
    }

    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    // 打印响应状态和头部
    fmt.Printf("Status: %d\n", resp.StatusCode)
    fmt.Println("Headers:")
    for k, v := range resp.Header {
        fmt.Printf("%s: %v\n", k, v)
    }

    // 可选:打印原始响应
    dump, _ := httputil.DumpResponse(resp, true)
    fmt.Printf("\nRaw response:\n%s\n", dump)

    // 读取响应体
    body, _ := io.ReadAll(resp.Body)
    fmt.Printf("\nBody:\n%s\n", body)
}

如果你需要手动处理重定向,可以这样实现:

func main() {
    client := &http.Client{}
    url := "http://localhost:5050/main?user_id=10&pw=abcd"

    for {
        req, _ := http.NewRequest("POST", url, nil)
        resp, err := client.Do(req)
        if err != nil {
            panic(err)
        }
        defer resp.Body.Close()

        fmt.Printf("Request to: %s\n", url)
        fmt.Printf("Status: %d\n", resp.StatusCode)

        if resp.StatusCode >= 300 && resp.StatusCode < 400 {
            // 获取重定向地址
            url = resp.Header.Get("Location")
            if url == "" {
                break
            }
            fmt.Printf("Redirecting to: %s\n\n", url)
            continue
        }

        body, _ := io.ReadAll(resp.Body)
        fmt.Printf("Final response body: %s\n", body)
        break
    }
}

第一个示例通过设置CheckRedirect函数返回http.ErrUseLastResponse来阻止自动重定向,让你能够检查中间响应。第二个示例展示了如何手动处理重定向链。

回到顶部