Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何从HTTP请求处理程序中获取状态代码_Go - Fatal编程技术网

Go 如何从HTTP请求处理程序中获取状态代码

Go 如何从HTTP请求处理程序中获取状态代码,go,Go,在我的请求处理程序中,我有一个条件语句,需要在其中获取http状态代码 func PostHandler(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) idStr := params["id"] // how would I get the 307 status code, to decide whether to redirect or not? if w.StatusCode

在我的请求处理程序中,我有一个条件语句,需要在其中获取http状态代码

func PostHandler(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    idStr := params["id"]

    // how would I get the 307 status code, to decide whether to redirect or not?
    if w.StatusCode != 307 { // does not work, no such field - why not???
        http.Redirect(w, r, idStr, 307)
    } else {
        RenderTemplate()
    }
}

m.HandleFunc("/{id:.*}", PostHandler).Methods("POST") // this is matched first to intercept POST requests with status 307
m.HandleFunc("/{id:.*}", MyHandler).Methods("GET", "POST")
我举了一个例子来帮助说明这个具体场景:

我将如何实现这一点

基本上,我使用307是因为我需要将我的POST值重新发送到http.Redirect(w,r,url,code)目的地。好吧,这似乎是最好的方法,但同样,没有状态码我也做不到

func PostHandler(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    idStr := params["id"]

    // how would I get the 307 status code, to decide whether to redirect or not?
    if w.StatusCode != 307 { // does not work, no such field - why not???
        http.Redirect(w, r, idStr, 307)
    } else {
        RenderTemplate()
    }
}

m.HandleFunc("/{id:.*}", PostHandler).Methods("POST") // this is matched first to intercept POST requests with status 307
m.HandleFunc("/{id:.*}", MyHandler).Methods("GET", "POST")
附加问题:使用307是一个糟糕的解决方案吗?如果是这样,还有什么更好的选择?

您的问题是:

我如何获得307状态码来决定是否重定向


您正在尝试决定是否需要在HTTP请求处理程序中重定向。在请求处理程序中,如果您没有收到状态代码,则会将状态代码作为响应的一部分发送。

我理解您的意图,但您的问题很容易误导。正如许多人所提到的,您无法访问以前发出的响应代码,这些代码是由于重定向而执行的(这不是因为Go没有提供响应代码,而是HTTP没有按照您希望的方式处理您的场景)。原始请求和重定向请求是在应用程序中两个不同时间发生的两个单独的HTTP请求。这意味着,如果全新的请求和重定向的请求完全相同,您就无法轻松区分它们

我想到了以下解决方案:

  • 发送307响应代码时,应该在
    位置
    头中提供一个新的URI。您可以选择不同的URL路径,以便将其路由到单独的处理程序(仅处理重定向请求)。另一种选择是使用相同的路径,但添加一个参数,例如将
    &redirected=1
    附加到URL–通过解析参数,您可以检测新的vs重定向请求

  • 如果可能,对重定向请求使用GET而不是POST。如果第二个请求需要POST数据,则需要从数据库或存储原始POST内容的任何位置获取该数据。根据我的理解,使用代码302而不是307将要求客户端始终使用GET方法跟踪重定向。然后可以使用
    Request.Method
    来区分新请求和重定向请求

  • 在应用程序中保留状态并跟踪已发布的内容。这需要每个请求都有一个唯一的标识符——如果您拥有并存储了它,那么您可以检查请求是全新的还是以前执行过(假设重定向)


  • 嘿,上面的例子很快就说明了整个问题。但是是的,你当然是对的,一个打字错误响应编写器没有可读的状态字段,因为它是您要返回的内容。如果这是您的意思,则请求有一个状态码成员。您所说的是什么状态码?状态代码是服务器(您的处理程序)响应我得到的:“r.StatusCode未定义(type*httpRequest没有字段或方法StatusCode”-知道该怎么办吗?该类型有一个
    StatusCode
    字段,但处理程序无法提供该字段,处理程序的任务是编写响应(通过
    http.ResponseWriter
    )而且标准的
    net/http
    包不会使当前部分写入的响应对处理程序可用。如果要将处理程序链接在一起,则您的任务是保持/传递任何必需的状态(如早期处理程序拾取的响应代码)在他们之间。我不明白为什么答案已经被提升了这么多。我需要在我的应用程序中使用这个功能(非常重要),我相信这应该是可能的,但这并不能真正帮助我找到特定问题的解决方案。也许我的示例不够清楚-我会尽快修改它,并准确地解释它应该做什么。@Dac0d3r:这是因为http客户端不发送状态代码。直到处理程序生成一个代码,无论是显式返回还是隐式返回,状态代码都不存在。如果要设置307,则可以自己调用WriteHeader,或使用http.Redirect helper函数。让我解释一下发生了什么(或预期的行为)。1)启动POST请求,2)第一个处理程序截获请求。3) post处理程序检查ResponseWriter是否具有状态代码307(4)如果没有(我将假定此请求是从表单提交触发的),我将使用307 post请求重定向到新目标。5) 处理程序将再次拦截此新重定向的307 POST请求,但现在,由于状态代码为307,它将不会重定向,而只是呈现模板。您是否有可能错过307 POST被POST处理程序再次拦截的机会?@Dac0d3r在发出第二个请求时,没有与之关联的307状态代码。是什么让您认为处理程序跟踪重定向,然后将它们和新的(重定向的)请求相匹配?您应该能够通过URL识别重定向请求(假设您没有重定向到与原始请求完全相同的URL)。@tomasz使用URL的想法实际上是一个不错的选择。在这种特殊情况下,它可能会起作用。然而,迄今为止最好的解决方案可能是Jackie Li在这里提出的解决方案——Martin Angers称之为“增强”响应编写器,用于拦截调用以获取状态代码。我尝试在这里实现它,但我还不能让它工作。我可以排除选项2和3,但我有点喜欢你的想法1a。最后,我决定创建一个自定义路由端点/{something:.*}/{else:.*}/{id:.*},我将其插入到表单action中,后跟一个可选的?redirectTo=id。谢谢。