2012-08-13 58 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) 
    } 
} 

這個技巧也適用於其他功能。