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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go URL

發(fā)布時間:2024/9/30 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go URL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

URL簡介

URL全稱Uniform Resource Location統(tǒng)一資源定位符,用于定位Internet中待訪問的文檔或資源。

URL提供了一種定位Internet上任意資源的手段,資源可通過各種不同的方案(比如HTTP、FTP、SMTP)來訪問,因此URL語法隨著方案不同而不同。

<schema>://<user>:<password>@<host>:<port>/<path>:<params>?<query>#<frag>

URL格式

scheme://[userinfo@]host[:port]/path[?query][#fragment] scheme://[userinfo]@[host]:[port]/path?key1=value1&key2=value2#fragment 格式描述
scheme方案/協(xié)議,比如http、https、ftp、file…
host主機(jī)名或IP地址,用于定位網(wǎng)絡(luò)位置
port服務(wù)端口
path主機(jī)上的資源路徑
query查詢字符串,使用&連接符鏈接的鍵值對。
fragment分段字段

URL編碼

  • URL不能有非ASCII字符,非ASCII使用%后跟兩位16進(jìn)制數(shù)表示。
  • URL中不能存在空格,空格使用+表示。
字符編碼
~%7
Space%20
%%25

net/url

net包對于網(wǎng)絡(luò)I/O提供了便攜式接口,包括TCP/IP、UDP、域名解析、UNIX Socket。盡管net包提供了大量訪問底層的接口,但大多數(shù)情況下,客戶端僅僅只需要最基本的接口。

Golang標(biāo)準(zhǔn)庫net/url包

  • 可用于獲取URL屬性
  • 解析URL并實現(xiàn)查詢轉(zhuǎn)義

URL解讀

URL結(jié)構(gòu)體

type URL struct {Scheme stringOpaque string // 編碼后的不透明數(shù)據(jù)User *Userinfo // 用戶名和密碼信息Host string // 主機(jī)地址 或 主機(jī):端口Path string // path (relative paths may omit leading slash)RawPath string // 詳細(xì)資源地址ForceQuery bool // append a query ('?') even if RawQuery is emptyRawQuery string // 已編碼查詢字符串Fragment string // 引用片段可用于表示文檔位置RawFragment string // encoded fragment hint (see EscapedFragment method) }

url.Parse

函數(shù)簽名

func Parse(rawurl string) (*URL, error)
  • 將原生的rawurl字符串解析轉(zhuǎn)換為URL結(jié)構(gòu)體,進(jìn)而獲取URL的相關(guān)屬性。
  • 原生URL可以是絕對地址,也可以是相對地址。

例如:

rawurl := "postgres://user:pass@host.com:5432/path1/path2/path3?k=v&k1=v1&k2=v2#f" u, err := url.Parse(rawurl) if err != nil {t.Fatal(err) }fmt.Printf("%v\n", u.Scheme) //postgres fmt.Printf("%v\n", u.Opaque) fmt.Printf("%v\n", u.User) //user:pass fmt.Printf("%v\n", u.Host) //host.com:5432 fmt.Printf("%v\n", u.Path) // /path1/path2/path3 fmt.Printf("%v\n", u.RawPath) fmt.Printf("%v\n", u.ForceQuery) //false fmt.Printf("%v\n", u.RawQuery) //k=v&k1=v1&k2=v2 fmt.Printf("%v\n", u.Fragment) //f fmt.Printf("%v\n", u.RawFragment)

URL.Opaque

url.Opaque表示透明類型的URL,即Scheme后沒有//的URL。

rawurl := "mailto:coding@gmail.com" u, err := url.Parse(rawurl) if err != nil {panic(err) }fmt.Printf("%v\n", u.Scheme) //mailto fmt.Printf("%v\n", u.Opaque) //coding@gmail.com

URL.User

URL結(jié)構(gòu)體中User字段包含了所有的認(rèn)證信息url.Userinfo

type Userinfo struct {username stringpassword stringpasswordSet bool }

通過Userinfo.Username()方法獲取username字段值

func (u *Userinfo) Username() string {if u == nil {return ""}return u.username }

通過Userinfo.Password()獲取password和passwordSet字段值

func (u *Userinfo) Password() (string, bool) {if u == nil {return "", false}return u.password, u.passwordSet }

例如:

rawurl := "postgres://user:pass@host.com:5432/path1/path2/path3?k=v&k1=v1&k2=v2#f" u, err := url.Parse(rawurl) if err != nil {panic(err) } userinfo := u.Userusername := userinfo.Username() fmt.Printf("%v\n", username) //userpassword, ok := userinfo.Password() if ok {fmt.Printf("%v\n", password) //pass }

URL.Host

url.Host同時包含主機(jī)名和端口,若端口存在則需要分割后才能提取。

例如:

rawurl := "postgres://user:pass@host.com:5432/path1/path2/path3?k=v&k1=v1&k2=v2#f" u, err := url.Parse(rawurl) if err != nil {panic(err) } host := u.Host fmt.Printf("%v\n", host) //host.com:5432 //判斷是否存在: ok := strings.Contains(host, ":") if ok {h := strings.Split(host, ":")fmt.Printf("%v\n", h) //[host.com 5432]addr := h[0]port := h[1]fmt.Printf("%v\n", addr) //host.comfmt.Printf("%v\n", port) //5432 }

url.ParseRequestURI

url.ParseRequestURI解析原生URL為一個URL結(jié)構(gòu)體

url.ParseRequestURI原生URL是一個絕對URL或絕對路徑

url.ParseRequestURI會忽略URL中的fragment分片參數(shù)

例如:

rawurl := "http://www.baidu.com/search?q=dotnet" u, err := url.ParseRequestURI(rawurl) if err != nil {t.Fatal(err) } t.Logf("url.Scheme: %v\f", u.Scheme) //url.Scheme: http t.Logf("url.Host: %v\f", u.Host) //url.Host: www.baidu.com t.Logf("url.Path: %v\f", u.Path) //url.Path: /search t.Logf("url.RawQuery: %v\f", u.RawQuery) //url.RawQuery: q=dotnet

url.PathEscape

URL中不允許存在空格和非ASCII字符,如果URL的資源路徑path字符串中存在空格和ASCII字符則可采用url.PathEscape將非ASCII字符轉(zhuǎn)義為使用%后跟2位16進(jìn)制數(shù)的形式,采用PathUnescape方法解碼還原為原始模式。

func PathEscape(s string) string

PathEscape將路徑字符串轉(zhuǎn)義,以便將其安全地放置在URL路徑段中。

func PathUnescape(s string) (string, error)
  • PathUnescape執(zhí)行與PathEscape的逆轉(zhuǎn)換
  • PathUnescape和QueryUnescape相同,只是PathUnescape不會將+加號轉(zhuǎn)換為空格。

例如:

rawurl := "http://www.baidu.com/search?id=1&name=管 理 員&pid=0#footer" encodeurl := url.PathEscape(rawurl) t.Log(encodeurl) http:%2F%2Fwww.baidu.com%2Fsearch%3Fid=1&name=%E7%AE%A1%20%E7%90%86%20%E5%91%98&pid=0%23footer decodeurl, err := url.PathUnescape(encodeurl) if err != nil {t.Fatal(err) } t.Log(decodeurl) http://www.baidu.com/search?id=1&name=管 理 員&pid=0#footer 轉(zhuǎn)義前轉(zhuǎn)義后
/%2F
?%3F
#%23
空格%20
  • PathEscape會將空格轉(zhuǎn)換為 %20
  • PathEscape不會對URL中的:和&進(jìn)行轉(zhuǎn)義編碼

url.QueryEscape

  • 對URL的查詢字符串進(jìn)行編碼和解碼
  • QueryEscape將URL中的查詢字符串轉(zhuǎn)義,以便安全地放置到URL查詢字符串中。

URL中不允許存在空格和非ASCII字符,如果URL的查詢字符串query字符串中存在空格和ASCII字符則可采用url.QueryEscape將非ASCII字符轉(zhuǎn)化為使用%后跟2位16進(jìn)制數(shù)的形式,采用QueryUnescape方法解碼還原為原始模式。

func QueryEscape(s string) string

例如:

rawurl := "http://www.baidu.com/search?id=1&name=管 理 員&pid=0#footer" encodeurl := url.QueryEscape(rawurl) t.Log(encodeurl) http%3A%2F%2Fwww.baidu.com%2Fsearch%3Fid%3D1%26name%3D%E7%AE%A1+%E7%90%86+%E5%91%98%26pid%3D0%23footer
  • QueryUnescape執(zhí)行與QueryEscape的逆轉(zhuǎn)換
func QueryUnescape(s string) (string, error)

例如:

rawurl := "http://www.baidu.com/search?id=1&name=管 理 員&pid=0#footer" encodeurl := url.QueryEscape(rawurl)decodeurl, err := url.QueryUnescape(encodeurl) if err != nil {t.Fatal(err) } t.Log(decodeurl) http://www.baidu.com/search?id=1&name=管 理 員&pid=0#footer 轉(zhuǎn)義前轉(zhuǎn)義后
:%3A
/%2F
?%3F
&%26
#%23
空格+
  • QueryEscape會將空格轉(zhuǎn)換為+加號
  • QueryEscape會將/路徑分隔符轉(zhuǎn)換為%2F

url.ParseQuery

func ParseQuery(query string) (Values, error) {m := make(Values)err := parseQuery(m, query)return m, err }

URL中的查詢字符串可采用url.ParseQuery解析生成一個url.Values字典實例。

例如:

rawurl := "http://www.baidu.com/search?id=1&name=admin&pid=0#footer" u, err := url.Parse(rawurl) if err != nil {panic(err) } query := u.RawQuery fmt.Printf("%v\n", query) //id=1&name=admin&pid=0values, err := url.ParseQuery(query) if err != nil {panic(err) } fmt.Printf("%v\n", values) //map[id:[1] name:[admin] pid:[0]] fmt.Printf("%v\n", values["id"][0]) //1 fmt.Printf("%v\n", values["name"][0]) //admin fmt.Printf("%v\n", values["pid"][0]) //0

封裝:從URL的查詢字符串中通過鍵獲得值

func GetQueryStringField(rawurl string, key string) (string, error) {u, err := url.Parse(rawurl)if err != nil {return "", err}query := u.RawQueryvalues, err := url.ParseQuery(query)if err != nil {return "", err}value := values.Get(key)return value, nil } rawurl := "http://www.baidu.com/search?id=1&name=admin&pid=0#footer" id, err := GetQueryStringField(rawurl, "id") if err != nil {panic(err) } fmt.Printf("%v\n", id) //1

url.Query

func (u *URL) Query() Values {v, _ := ParseQuery(u.RawQuery)return v } rawurl := "http://www.baidu.com/search?id=1&name=admin&pid=0#footer" u, err := url.Parse(rawurl) if err != nil {panic(err) }values := u.Query() fmt.Printf("%v\n", values) //map[id:[1] name:[admin] pid:[0]]id := values.Get("id") fmt.Printf("%v\n", id) //1

重置查詢字符串鍵值對

rawurl := "http://www.baidu.com/search?id=1&name=admin&pid=0#footer" u, err := url.Parse(rawurl) if err != nil {panic(err) }values := u.Query() values.Set("id", "100")u.RawQuery = values.Encode() t.Log(u) //http://www.baidu.com/search?id=100&name=admin&pid=0#footer

url.Values

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

將url.Values轉(zhuǎn)換為查詢字符串

func BuildHTTPQueryString(values url.Values) string {var keys []stringfor k := range values {keys = append(keys, k)}sort.Strings(keys)bb := bytes.Buffer{}for _, key := range keys {val := values.Get(key)bb.WriteString(key)bb.WriteString("=")bb.WriteString(val)bb.WriteString("&")}return strings.TrimRight(bb.String(), "&") } values := url.Values{} values.Add("id", "1") values.Add("name", "admin") values.Add("pid", "0")queryString := BuildHTTPQueryString(values) fmt.Printf("%v\n", queryString) //id=1&name=admin&pid=0

values.Encode

例如:HTTP請求將URL傳遞過來的參數(shù)編碼為以&連接的字符串

values := url.Values{} values.Add("app_id", "2016073100129537") values.Add("out_trade_no", "2201010101") values.Add("method", "alipay.trade.app.pay") values.Add("notify_url", "http://203.86.24.181:3000/alipay") values.Add("timestamp", "2017-11-10 17:54:34") values.Add("sign_type", "RSA2") values.Add("version", "1.0") encode := values.Encode() fmt.Printf("%v\n", encode) app_id=2016073100129537&method=alipay.trade.app.pay&notify_url=http%3A%2F%2F203.86.24.181%3A3000%2Falipay&out_trade_no=2201010101&sign_type=RSA2&timestamp=2017-11-10+17%3A54%3A34&version=1.0

總結(jié)

以上是生活随笔為你收集整理的Go URL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。