猿问

Go Web 服务器自动重定向 POST 请求

一段时间以来,我一直试图解决一个奇怪的问题。在逐步完成大量 Angular 代码后,我注意到在通过 Charles 将请求记录到我的服务器时有些奇怪。

当我发布到 url 时/myurl,请求从未真正到达我的服务器。相反,它得到一个 301 响应,然后一个 GET 请求命中我的服务器。

这令人难以置信。有没有其他人遇到过这个问题?我已经上传了我的 Charles 日志截图,以防您有兴趣。

作为参考,这就是我的服务器的样子:


type FormStruct struct {

    Test string

}


func PHandler(w http.ResponseWriter, r *http.Request) {

    var t FormStruct


    req, _ := httputil.DumpRequest(r, true)


    log.Println(string(req))

    log.Println(r.Method) // GET

    log.Println(r.Body)


    decoder := json.NewDecoder(r.Body)

    err := decoder.Decode(&t)

    log.Println("Decoding complete")

    if err != nil {

        log.Println("Error")

        panic(err.Error()+"\n\n")

    }

    log.Println(t.Test)


    w.Write([]byte("Upload complete, no errors"))

}


func main() {

    http.HandleFunc("/myurl/", PHandler)    

    fmt.Println("Go Server listening on port 8001")

    http.ListenAndServe(":8001", nil)

}


心有法竹
浏览 296回答 1
1回答

天涯尽头无女友

解释很简单:因为您"/myurl/"在注册时使用了路径PHandler(注意尾部斜杠/!),但您将浏览器定向到/myurl(注意没有尾部斜杠)。默认情况下,http包实现将执行(发回)重定向请求,因此如果浏览器跟随它(它会),新的 URL 将匹配注册的路径。这在 type 中记录http.ServeMux:如果已经注册了子树并且接收到命名子树根而没有其尾部斜杠的请求,ServeMux 将该请求重定向到子树根(添加尾部斜杠)。此行为可以通过不带斜杠的单独路径注册来覆盖。例如,注册“/images/”会导致 ServeMux 将对“/images”的请求重定向到“/images/”,除非已经单独注册了“/images”。如果您将浏览器直接/myurl/定向到,则不会遇到重定向。或者,如果您不需要处理有根的子树而只需要处理单个路径(例如/myurl),则仅将您的处理程序注册到该单个路径:http.HandleFunc("/myurl", PHandler)然后当然将您的浏览器/myurl定向到,您也不会遇到任何重定向。...或者如文档所建议的:如果您确实需要,则将两个路径注册到您的处理程序:http.HandleFunc("/myurl", PHandler) http.HandleFunc("/myurl/", PHandler)现在无论您调用(/myurl或/myurl/)哪个路径,都将导致调用您的处理程序而不会发生任何重定向。笔记:在您将重定向发送回浏览器的情况下,浏览器不会重复 POST 请求(而只是一个“简单”的 GET 请求)。一般来说,浏览器不会将 POST 数据发送到重定向 URL,因为浏览器没有资格决定您是否愿意将相同的数据发送到您打算发送到原始 URL 的新 URL(考虑密码,信用卡号和其他敏感数据)。但不要试图规避它,只需使用处理程序的注册路径来 POST 或上述任何其他提示。
随时随地看视频慕课网APP

相关分类

Go
我要回答