在golang中的http.Request對象中的所有屬性,沒有可以直接獲取完整URL的方法。但可以通過host和請求地址進行拼接。具體方法是在Request.Host中獲取hostname,Request.RequestURI獲取相應的請求地址。
對於協議的判斷,如區分http還是https協議,一開始嘗試通過r.Proto屬性判斷,但是發現該屬性不管是http,還是https都是返回HTTP/1.1,又尋找了下發現TLS屬性,在https協議下有對應值,在http下為nil。
主要技術點:
1.通過r.TLS是否為nil判斷scheme是http或https:
r.TLS == nil ---> http
r.TLS != nil ---> https
2.通過r.Proto獲取http版本號,例如:HTTP/1.1
3.通過r.Host獲取地址及端口號,例如:localhost:9090或127.0.0.1:8000
4.通過r.RequestURI獲取目錄及參數,例如:/index?id=2
完整代碼:
1 package main 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 "strings" 8 ) 9 10 func index(w http.ResponseWriter, r *http.Request) { 11 fmt.Println("--------------------") 12 fmt.Println(r.Proto) 13 // output:HTTP/1.1 14 fmt.Println(r.TLS) 15 // output: <nil> 16 fmt.Println(r.Host) 17 // output: localhost:9090 18 fmt.Println(r.RequestURI) 19 // output: /index?id=1 20 21 scheme := "http://" 22 if r.TLS != nil { 23 scheme = "https://" 24 } 25 fmt.Println(strings.Join([]string{scheme, r.Host, r.RequestURI}, "")) 26 // output: http://localhost:9090/index?id=1 27 } 28 29 func GetURL(r *http.Request)(Url string) { 30 scheme := "http://" 31 if r.TLS != nil { 32 scheme = "https://" 33 } 34 return strings.Join([]string{scheme, r.Host, r.RequestURI}, "") 35 } 36 37 func main() { 38 http.HandleFunc("/index", index) 39 40 err := http.ListenAndServe(":9090", nil) 41 if err != nil { 42 log.Fatal("ListenAndServe: ", err) 43 } 44 }