日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go Web:URLs

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go Web:URLs 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

URL也是一個結構體:

type URL struct {Scheme stringOpaque string // encoded opaque dataUser *Userinfo // username and password informationHost string // host or host:portPath string // path (relative paths may omit leading slash)RawPath string // encoded path hint (see EscapedPath method)ForceQuery bool // append a query ('?') even if RawQuery is emptyRawQuery string // encoded query values, without '?'Fragment string // fragment for references, without '#' }

URL結構表示解析之后的URL,一般格式為:

[scheme:][//[userinfo@]host][/]path[?query][#fragment]

由于path和query部分只能使用大小寫字母、數字以及有限的幾個特殊標點,其它所有的字符都需要進行URL編碼:百分號+2位16進制數。例如,空格被編碼為"%20",斜線被編碼為"%2f",有時候query的value中空格會被編碼為"+"。

例如,query部分被編碼后的內容如下:

name=Hiram%20Veeblefeetzer&age=35&country=Madagascar+abc

它表示3個key/value:name="Hiram Veeblefeetzer"、age=35、country=Madagascar abc。

關于URL,其中:

  • Host字段是包含host和port兩部分的,如果需要分別返回host、port,使用URL.Hostname、URL.Port
  • User字段包含了Username和Password,要分別返回它們,使用URL.User.Username(),URL.User.Password()
  • Path字段表示解碼后的URL路徑,也就是不帶"%"的普通字符串路徑
  • RawPaht字段表示編碼后的安全路徑,即帶上了"%"的路徑
  • RawQuery字段表示編碼后的Query,即打上了"%"的query字符串,它包含了所有key/value,要分離每個key/value,使用ParseQuery()方法將它們解析到一個map中

URL解析示例

使用URL的Parse(string)方法可以將字符串構造成一個URL對象,并返回這個URL對象的指針。

現在使用這個方法來構造一個URL對象,并解析其中的各個部分:

package mainimport "fmt" import "net/url"func main() {// 將字符串構造成URL對象s := "postgres://user:pass@host.com:5432/path?k=v#f"u, err := url.Parse(s)if err != nil {panic(err)}// 獲取schema部分fmt.Println(u.Scheme)// User字段包含了Username和Password,需要分別獲取fmt.Println(u.User)fmt.Println(u.User.Username())p, _ := u.User.Password()fmt.Println(p)// Host字段包含了hostname和portfmt.Println(u.Host)fmt.Println(u.Hostname())fmt.Println(u.Port())// 取得Path和Fragment字段fmt.Println(u.Path)fmt.Println(u.Fragment)// 取得query的key/value// 要取出各個key/value,使用ParseQuery()將RawQuery字段解析成map// key是字符串,value是字符串的slice,如果有key相同,則多個值放進這個slicefmt.Println(u.RawQuery)m, _ := url.ParseQuery(u.RawQuery)fmt.Println(m)fmt.Println(m["k"][0]) }

結果:

postgres user:pass user pass host.com:5432 host.com 5432 /path f k=v map[k:[v]] v

構造URL

URL的Parse(string)方法可以將字符串構造成一個URL對象,URL的String()方法可以返回編碼后的URL值。

例如:

urlstr := "http://www.cnblogs.com/f-ck-need-u" myurl,_ := url.Parse(urlstr) fmt.Println(myurl.String())

輸出:

http://www.cnblogs.com/f-ck-need-u

由于URL的path和query部分可能包含特殊字符,直接使用純字符串構造URL會不安全。應該使用另外兩個函數將普通字符轉換成編碼后的字符:

func PathEscape(s string) string func QueryEscape(s string) string

再將編碼之后的path和query作為Parse()方法的一部分。

例如:

package mainimport ("fmt""net/url" )func main() {// 要構造:http://www.example.int/下// Path: search// Query: food=pie aaa// action=like// 的URLs := "http://www.example.int"p := "search"path := url.PathEscape(p)// query部分qfood := "pie aaa"qaction := "like"qqfood := url.QueryEscape(qfood)qqaction := url.QueryEscape(qaction)// 將query組合起來query := "food=" + qqfood + "&action=" + qqaction// 構造urlmyurlstr := s + "/" + path + "?" + querymyurl, err := url.Parse(myurlstr)if err != nil {panic(err)}// 解析URLfmt.Println(myurl.String())// 解析url的query部分fmt.Println(myurl.RawQuery)qmaps, _ := url.ParseQuery(myurl.RawQuery)fmt.Println(qmaps["food"])fmt.Println(qmaps["action"]) }

這很麻煩,對于Query部分,更好的方法是使用Values.Encode()方法,見后文。

url Path部分

在URL結構中:有Path和RawPath兩個字段

type URL struct{...Path string // path (relative paths may omit leading slash)RawPath string // encoded path hint (see EscapedPath method)... }

其中Path是解碼后的路徑,RawPath是編碼后的路徑。

前面解釋了PathEscape()函數,它是將字符串轉換為編碼后的字符串,可以直接將編碼后的結果作為構造url的path部分,這樣是最安全的構造方式。

除此之外,還有一個EscapePath()方法:如果RawPath存在且有效,則直接返回RawPath字段的值,如果不存在,則EscapePath()自己計算一個編碼后的路徑。

URL.String()方法是直接調用EscapePath()來構造路徑部分的。

Userinfo

type Userinfofunc User(username string) *Userinfofunc UserPassword(username, password string) *Userinfofunc (u *Userinfo) Password() (string, bool)func (u *Userinfo) String() stringfunc (u *Userinfo) Username() string

User()函數構造一個Userinfo,但只包含Username不包含password。

UserPassword()函數構造一個Userinfo,包含Username和password,但因為明文顯示,不建議使用。

String()返回"username[:password]"格式的username和Password。

Username()和Password()分別返回對應的部分。

Query部分

URL結構中有一個RawQuery字段:

type URL struct {...RawQuery string... }

RawQuery字段是編碼后的query。

有幾個方法:

func (u *URL) Query() Values

它讀取RawQuery字段的值并返回Values類型。但會直接丟棄錯誤或畸形的query部分,如果要檢查錯誤或畸形,使用ParseQuery()函數。

注意上面Query()的返回值是Values類型,它是一個map結構:

type Values map[string][]stringfunc ParseQuery(query string) (Values, error)func (v Values) Add(key, value string)func (v Values) Del(key string)func (v Values) Encode() stringfunc (v Values) Get(key string) stringfunc (v Values) Set(key, value string)

ParseQuery()函數解析給定字符串query并將query的各個部分填充到返回值類型Values的map結構中,同時會檢查錯誤。

Add()、Del()、Set()和Get()都用來操作Values的map結構,意義都很清晰。唯一需要注意的是,Add()是追加操作,Set()是替換已有值,如果操作的key不存在,則直接創建。

Encode()是將Values中的數據根據key排序后編碼成URL的query,且是編碼后的query。

下面是一個用法:

package mainimport ("fmt""net/url" )func main() {s := "http://www.example.int"p := "search"path := url.PathEscape(p)// query部分values := url.Values{}values.Set("food","pie aaa")values.Add("action","like")values.Add("name","abc")values.Add("name","def")values.Add("name","gh")// Encode() == "action=like&food=pie+aaa&name=abc&name=def&name=gh"query := values.Encode()// 構造urlmyurlstr := s + "/" + path + "?" + querymyurl, err := url.Parse(myurlstr)if err != nil {panic(err)}// 解析urlfmt.Println(myurl.String()) }

轉載于:https://www.cnblogs.com/f-ck-need-u/p/10020927.html

總結

以上是生活随笔為你收集整理的Go Web:URLs的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。