2012-08-13 154 views
2

我正在读的源代码goto重定向,我发现下面的代码goto/talk/0/main.go如何使绝对路径HTTP在golang

http.Redirect(w, r, url, http.StatusFound) 

根据上下文,url是一个绝对路径,以及预期绝对路径重定向。但是,随着golang/http/redirect提到:

Redirect答复与重定向到URL,其可以是相对于该请求路径的路径请求。

它作为相对路径重定向的结果。我不知道http.Redirect之前是否做过绝对路径重定向,但现在不是。

那么如何在golang中做出绝对路径重定向呢? 我搜索了互联网,但没有发现任何人,任何人都可以帮我吗? 在此先感谢。

回答

3

我终于发现,执行的绝对路径重定向,将url必须是一个完整的URL,如http://www.stackoverflow.comhttps://github.com,但不www.stackoverflow.com

+0

你能添加一个链接到doc吗? – 2012-08-13 15:36:12

+1

@orian [链接] http://golang.org/pkg/net/http/#Redirect [链接],这里是http.Redirect的文档,但它提到前缀“http://”将执行绝对路径重定向。 – carter2000 2012-08-14 01:05:33

7

当你去golang文档http.Redirect,实际上你可以点击蓝色标题:

FUNC Redirect

它会带给你的源代码上市这是不言自明:

// Redirect replies to the request with a redirect to url, 
// which may be a path relative to the request path. 
func Redirect(w ResponseWriter, r *Request, urlStr string, code int) { 
    if u, err := url.Parse(urlStr); err == nil { 
     // If url was relative, make absolute by 
     // combining with request path. 
     // The browser would probably do this for us, 
     // but doing it ourselves is more reliable. 

     // NOTE(rsc): RFC 2616 says that the Location 
     // line must be an absolute URI, like 
     // "http://www.google.com/redirect/", 
     // not a path like "/redirect/". 
     // Unfortunately, we don't know what to 
     // put in the host name section to get the 
     // client to connect to us again, so we can't 
     // know the right absolute URI to send back. 
     // Because of this problem, no one pays attention 
     // to the RFC; they all send back just a new path. 
     // So do we. 
     oldpath := r.URL.Path 
     if oldpath == "" { // should not happen, but avoid a crash if it does 
      oldpath = "/" 
     } 
     if u.Scheme == "" { 
      // no leading http://server 
      if urlStr == "" || urlStr[0] != '/' { 
       // make relative path absolute 
       olddir, _ := path.Split(oldpath) 
       urlStr = olddir + urlStr 
      } 

      var query string 
      if i := strings.Index(urlStr, "?"); i != -1 { 
       urlStr, query = urlStr[:i], urlStr[i:] 
      } 

      // clean up but preserve trailing slash 
      trailing := strings.HasSuffix(urlStr, "/") 
      urlStr = path.Clean(urlStr) 
      if trailing && !strings.HasSuffix(urlStr, "/") { 
       urlStr += "/" 
      } 
      urlStr += query 
     } 
    } 

    w.Header().Set("Location", urlStr) 
    w.WriteHeader(code) 

    // RFC2616 recommends that a short note "SHOULD" be included in the 
    // response because older user agents may not understand 301/307. 
    // Shouldn't send the response for POST or HEAD; that leaves GET. 
    if r.Method == "GET" { 
     note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + 
       "</a>.\n" 
     fmt.Fprintln(w, note) 
    } 
} 

这个技巧也适用于其他功能。