Go Web服务器会自动重定向POST请求 [英] Go web server is automatically redirecting POST requests

查看:165
本文介绍了Go Web服务器会自动重定向POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图解决一个



就像一个引用,这就是我的服务器的样子:

  type FormStruct struct {
测试字符串


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)

解码器:= json.NewDecoder(r.Body)
err:= decoder.Decode(& t)
log.Println(Decoding complete )
if err!= nil {
log.Println(Error)
panic(err.Error()+\\\
\\\

}
log.Println(t.Test)

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


func main(){
http.HandleFunc(/ myurl /,PHandler)
fmt.Println(Go Server listen on 8001 )
http.ListenAndServe(:8001,nil)
}


解决方案

解释很简单:当您注册 PHandler 时,因为您使用了/ myurl / / code>(请注意斜线 / !!),但是您将浏览器指向 / myurl 没有结尾的斜线)。默认情况下, http 包实现将执行(发送)重定向请求,所以如果浏览器遵循它(它会),新URL将匹配注册路径。 / p>

http.ServeMux


如果子树已注册并接收到一个请求,命名该子树根没有其结尾的斜杠,ServeMux将该请求重定向到子树根(添加尾部斜杠)。此行为可以通过单独注册路径而不使用结尾斜杠来覆盖。例如,注册/ images /会导致ServeMux将/ images的请求重定向到/ images /,除非已单独注册/ images。

如果您将浏览器直接指向 / myurl / ,则不会遇到重定向。



或者,如果你不需要处理一个根目录的子树但是只有一个路径(例如 / myurl ),那么只注册你的处理程序到这个单一的路径:

  http.HandleFunc(/ myurl,PHandler)

然后当然你的浏览器直接指向 / myurl ,你也不会遇到任何重定向。 / p>

...或者如文档所示:如果您真的需要,请将两个路径注册到您的处理程序:

<$ p
http.HandleFunc(/ myurl /,PHandler)

现在无论您调用哪个路径( / myurl / myurl /


在您将重定向发送回浏览器的情况下,浏览器不会重复POST请求(而只是一个简单的GET请求)。



一般来说,浏览器不会将POST数据发送到重定向URL,因为浏览器没有资格决定是否愿意将相同的数据发送到您希望发送到新URL的数据原始URL(考虑密码,信用卡号码和其他敏感数据)。但是不要试图绕过它,只需使用你的处理程序的注册路径来POST,或者上面提到的任何其他提示。



您可以阅读更多关于这里的主题:



为什么HTTP没有POST重定向?


I've been trying to solve a weird problem for quite some time now. After stepping through lots of angular code, I noticed something weird while logging requests to my server through Charles.

When I post to a url /myurl the request never actually hits my server. Instead, it gets a 301 response and THEN a GET request hite my server.

This is incredibly puzzling. Has anyone else run into this problem? I've uploaded a screenshot of my Charles log incase you are interested.

Just as a reference, this is what my server looks like:

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)
}

解决方案

The explanation is simple: because you used the "/myurl/" path when you registered your PHandler (note the trailing slash /!) but you directed your browser to /myurl (note there is no trailing slash). And by default the http package implementation will perform (send back) a redirect request so if the browser follows it (it will), the new URL will match the registered path.

This is documented at type http.ServeMux:

If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.

Should you direct your browser directly to /myurl/, you would not experience a redirect.

Or if you don't need to handle a rooted subtree but only a single path (e.g. /myurl), then register your handler only to this single path:

http.HandleFunc("/myurl", PHandler)

And then of course direct your browser to /myurl, and you will not experience any redirect either.

...Or as the documentation suggests: register both paths to your handler if you really need it:

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

And now no matter which path you call (/myurl or /myurl/), both will result in calling your handler without any redirection taking place.

Notes:

In your situation when a redirect was sent back to the browser, the browser will not repeat the POST request (but rather just a "simple" GET request).

Generally speaking a browser will not send POST data to a redirect URL because the browser is not qualified to decide if you're willing to send the same data to the new URL what you intended to send to the original URL (think about passwords, credit card numbers and other sensitive data). But don't try to circumvent it, simply use registered path of your handler to POST to, or any of the other tips mentioned above.

You can read more on the subject here:

Why doesn't HTTP have POST redirect?

这篇关于Go Web服务器会自动重定向POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆