Go URL

网友投稿 4596 2022-10-30

Go URL

Go URL

URL简介

URL全称Uniform Resource Location统一资源定位符,用于定位Internet中待访问的文档或资源。

URL提供了一种定位Internet上任意资源的手段,资源可通过各种不同的方案(比如HTTP、FTP、SMTP)来访问,因此URL语法随着方案不同而不同。

://:@:/:?#

URL格式

scheme://[userinfo@]host[:port]/path[?query][#fragment]scheme://[userinfo]@[host]:[port]/path?key1=value1&key2=value2#fragment

格式

描述

scheme

方案/协议,比如data-id="t31e458f-noUdd7e6" style="height: 30px;">

host

主机名或IP地址,用于定位网络位置

port

服务端口

path

主机上的资源路径

query

查询字符串,使用&连接符链接的键值对。

fragment

分段字段

URL编码

URL不能有非ASCII字符,非ASCII使用​​%​​后跟两位16进制数表示。URL中不能存在空格,空格使用​​+​​表示。

字符

编码

~

%7

Space

%20

%

%25

net/url

​​net​​​包对于网络I/O提供了便携式接口,包括TCP/IP、UDP、域名解析、UNIX Socket。尽管​​net​​包提供了大量访问底层的接口,但大多数情况下,客户端仅仅只需要最基本的接口。

Golang标准库​​net/url​​包

可用于获取URL属性解析URL并实现查询转义

URL解读

URL结构体

type URL struct { Scheme string Opaque string // 编码后的不透明数据 User *Userinfo // 用户名和密码信息 Host string // 主机地址 或 主机:端口 Path string // path (relative paths may omit leading slash) RawPath string // 详细资源地址 ForceQuery bool // append a query ('?') even if RawQuery is empty RawQuery string // 已编码查询字符串 Fragment string // 引用片段可用于表示文档位置 RawFragment string // encoded fragment hint (see EscapedFragment method)}

url.Parse

函数签名

func Parse(rawurl string) (*URL, error)

将原生的​​rawurl​​​字符串解析转换为​​URL​​结构体,进而获取URL的相关属性。原生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) //postgresfmt.Printf("%v\n", u.Opaque)fmt.Printf("%v\n", u.User) //user:passfmt.Printf("%v\n", u.Host) //host.com:5432fmt.Printf("%v\n", u.Path) // /path1/path2/path3fmt.Printf("%v\n", u.RawPath)fmt.Printf("%v\n", u.ForceQuery) //falsefmt.Printf("%v\n", u.RawQuery) //k=v&k1=v1&k2=v2fmt.Printf("%v\n", u.Fragment) //ffmt.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) //mailtofmt.Printf("%v\n", u.Opaque) //coding@gmail.com

URL.User

URL结构体中User字段包含了所有的认证信息​​url.Userinfo​​

type Userinfo struct { username string password string passwordSet 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​​同时包含主机名和端口,若端口存在则需要分割后才能提取。

例如:

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.Hostfmt.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.com fmt.Printf("%v\n", port) //5432}

url.ParseRequestURI

​​url.ParseRequestURI​​解析原生URL为一个URL结构体

​​url.ParseRequestURI​​原生URL是一个绝对URL或绝对路径

​​url.ParseRequestURI​​​会忽略URL中的​​fragment​​分片参数

例如:

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

url.PathEscape

URL中不允许存在空格和非ASCII字符,如果URL的资源路径​​path​​​字符串中存在空格和ASCII字符则可采用​​url.PathEscape​​​将非ASCII字符转义为使用​​%​​​后跟2位16进制数的形式,采用​​PathUnescape​​方法解码还原为原始模式。

func PathEscape(s string) string

PathEscape将路径字符串转义,以便将其安全地放置在URL路径段中。

func PathUnescape(s string) (string, error)

PathUnescape执行与PathEscape的逆转换PathUnescape和QueryUnescape相同,只是PathUnescape不会将​​+​​加号转换为空格。

例如:

rawurl := "理 员&pid=0#footer"encodeurl := url.PathEscape(rawurl)t.Log(encodeurl)

err := url.PathUnescape(encodeurl)if err != nil { t.Fatal(err)}t.Log(decodeurl)

理 员&pid=0#footer

转义前

转义后

/

%2F

?

%3F

#

%23

空格

%20

PathEscape会将空格转换为​​%20​​PathEscape不会对URL中的​​:​​​和​​&​​进行转义编码

url.QueryEscape

对URL的查询字符串进行编码和解码QueryEscape将URL中的查询字符串转义,以便安全地放置到URL查询字符串中。

URL中不允许存在空格和非ASCII字符,如果URL的查询字符串​​query​​​字符串中存在空格和ASCII字符则可采用​​url.QueryEscape​​​将非ASCII字符转化为使用​​%​​​后跟2位16进制数的形式,采用​​QueryUnescape​​方法解码还原为原始模式。

func QueryEscape(s string) string

例如:

rawurl := "理 员&pid=0#footer"encodeurl := url.QueryEscape(rawurl)t.Log(encodeurl)

QueryUnescape(s string) (string, error)

例如:

rawurl := "理 员&pid=0#footer"encodeurl := url.QueryEscape(rawurl)decodeurl, err := url.QueryUnescape(encodeurl)if err != nil { t.Fatal(err)}t.Log(decodeurl)

理 员&pid=0#footer

转义前

转义后

:

%3A

/

%2F

?

%3F

&

%26

#

%23

空格

+

QueryEscape会将空格转换为​​+​​加号QueryEscape会将​​/​​​路径分隔符转换为​​%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 := "err := url.Parse(rawurl)if err != nil { panic(err)}query := u.RawQueryfmt.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]) //1fmt.Printf("%v\n", values["name"][0]) //adminfmt.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.RawQuery values, err := url.ParseQuery(query) if err != nil { return "", err } value := values.Get(key) return value, nil}

rawurl := "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 := "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 := "err := url.Parse(rawurl)if err != nil { panic(err)}values := u.Query()values.Set("id", "100")u.RawQuery = values.Encode()t.Log(u) //Values map[string][]stringfunc (v Values) Get(key string) stringfunc (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​​转换为查询字符串

func BuildHTTPQueryString(values url.Values) string { var keys []string for 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传递过来的参数编码为以​​&​​连接的字符串

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", ""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¬ify_url=http%3A%2F%2F203.86.24.181%3A3000%2Falipay&out_trade_no=2201010101&sign_type=RSA2×tamp=2017-11-10+17%3A54%3A34&version=1.0

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:springboot如何读取自定义属性
下一篇:类图中的关系
相关文章

 发表评论

暂时没有评论,来抢沙发吧~