如何检测是否调用了重定向

时间:2015-02-16 20:45:37

标签: go

我有以下代码

package main

import (
    "log"
    "net/http"
)

func fooHandler(w http.ResponseWriter, r *http.Request) {
    // Here an if condition, if should redirect or not
    http.Redirect(w, r, "http://www.google.com", 301)
    // Do something....
    // Call function if redirect was invoked

}

func main() {
    http.HandleFunc("/", fooHandler)
    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

如果在响应对象中写入重定向,我如何检测?

3 个答案:

答案 0 :(得分:0)

如果我理解正确,你需要更多的东西:

func fooHandler(w http.ResponseWriter, r *http.Request) {
    // Here an if condition, if should redirect or not
    if needToRedirect {
        http.Redirect(w, r, "http://www.google.com", 301)
        return
    }
    // Do something....
    // Call function if redirect was invoked
    // render template
}

通常情况下,我们会按照退出 早期咒语进行操作。在您的示例中,一旦您确定需要重定向用户(忽略您可能想要执行的任何其他日志记录),最好立即返回。

答案 1 :(得分:0)

您可以查看回复的状态(适用于3xx redirection status code),如http REST driver所示:

    req, err = http.NewRequest(verb, url, body)

    if err != nil {
        return nil, err
    }

    for k, v := range headers {
        req.Header.Add(k, v)
    }

    resp, err = d.httpClient.Do(req)

    if err != nil {
        return nil, err
    }

    log.Printf("Exec responce: %v\n", resp)

    statusCode := resp.StatusCode


    if statusCode == 307 { // Temporary Redirect

        // For instance (put your own code here)

        redirectUrl, ok := resp.Header["Location"]
        if !ok {
            return nil, fmt.Errorf("%s %s", "Failed to redirect:", "header key 'Location' wasn't found")
        }
        log.Printf("Redirecting: '%s' --> '%s'", url, redirectUrl[0])
        url = redirectUrl[0]
        continue

    }

答案 2 :(得分:0)

首先,我必须同意这里的回复,说明最好在重定向后立即返回。但是,如果你决定在之后做一些其他的事情(无论你是否重定向),然后是一个仅在使用重定向时调用的函数,那么你可以按照以下方式做一些事情:

func fooHandler(w http.ResponseWriter, r *http.Request) {
    if needToRedirect {
        http.Redirect(w, r, "http://www.google.com", 301)
        defer func() {
            // stuff that only happens if redirected, but happens last
        }()
    }
    // stuff that happens whether redirected or not
    // note that this will happen before the deferred func is called
}

以下是defer的文档:http://blog.golang.org/defer-panic-and-recover

这很简单。延迟调用将在周围函数(fooHandler)返回后执行,但它仍然可以访问fooHandler范围内的任何内容,包括命名返回值。同样重要的是要注意,即使在恐慌期间也会调用延迟函数,但除非调用recover(),否则不会发生任何事情。

编辑:这是一个如何运作的愚蠢示例:http://play.golang.org/p/5TgCv4O_rA