golang net.url 标准库
Go 语言标准库中的 net/url 包提供了用于 URL 解析、构建和查询的功能。这个包使我们能够处理 URL,从中提取出各个部分,比如协议、主机、路径和查询参数等。以下是 net/url 包中一些常用的功能:
- 解析URL:使用 Parse 函数可以将 URL 字符串解析为 url.URL 结构体。
go
u, err := url.Parse("https://example.com/path?key1=value1&key2=value2")
if err != nil {
log.Fatal(err)
}
- 构建URL:可以使用 url.URL 结构体中的方法来构建 URL。
go
u := &url.URL{
Scheme: "https",
Host: "example.com",
Path: "/path",
RawQuery: "key1=value1&key2=value2",
}
- 查询参数:url.Values 类型表示 URL 查询参数,可以用于构建和解析查询参数。
go
u, _ := url.Parse("https://example.com/path?key1=value1&key2=value2")
queryValues := u.Query()
fmt.Println(queryValues.Get("key1")) // 输出: value1
fmt.Println(queryValues.Get("key2")) // 输出: value2
其它功能:url.URL 结构体中还提供了一些其他方法,比如获取完整的 URL 字符串、处理路径、解析主机等等。
福利彩蛋:没有好玩的 API 接口?上百款免费接口等你来,免费 API,免费 API 大全
基本类型结构
golang
<schema>://<user>:<password>@<host>:<port>/<path>:<params>?<query>#<frag>
参数描述:
名称 | 描述 |
---|---|
scheme | 方案是如何访问指定资源的主要标识符,他会告诉负责解析URL应用程序应该使用什么协议 |
user | 用户名 |
password | 密码 |
host | 主机组件标识了因特网上能够访问资源的宿主机器,可以有主机名或者是 IP 地址来表示 |
port | 端口标识了服务器正在监听的网络端口。默认端口号是 80 |
path | URL 的路径组件说明了资源位于服务器的什么地方 |
params | URL 中通过协议参数来访问资源,比名值对列表,分号分割来进行访问 |
query | 字符串是通过提问问题或进行查询来缩小请求资源类的范围 |
frag | 为了引用部分资源或资源的一个片段,比如 URL 指定 HTML 文档中一个图片或一个小节 |
基本结构
golang
type URL struct {
Scheme string //具体指访问服务器上的资源使用的哪种协议
Opaque string // 编码后的不透明数据
User *Userinfo // 用户名和密码信息,有些协议需要传入明文用户名和密码来获取资源,比如 FTP
Host string // host或host:port,服务器地址,可以是 IP 地址,也可以是域名信息
Path string //路径,使用"/"分隔
RawPath string // 已编码的路径提示(参见EscapedPath方法)
ForceQuery bool // 添加一个查询('?'),即使RawQuery为空
RawQuery string // 编码后的查询字符串,没有'?'
Fragment string // 引用的片段(文档位置),没有'#'
}
常用方法
地址解析Parse,详细参数
golang
func main() {
urlString := "https://admin:passwd@www.baidu.com:80/search?mq=test#12345"
u, err := url.Parse(urlString)
if err != nil {
fmt.Println("parse error ", err)
}
fmt.Printf("u type is %T, u is %#v\n", u, u)
/*
u type is *url.URL,
u is &url.URL{
Scheme:"https", Opaque:"", User:(*url.Userinfo)(0xc000088150),
Host:"www.baidu.com:80", Path:"/search", RawPath:"", ForceQuery:false,
RawQuery:"mq=test", Fragment:"12345"
}
*/
fmt.Printf("u.Scheme is %#v\n", u.Scheme) // u.Scheme is "https"
fmt.Printf("u.Opaque is %#v\n", u.Opaque) // u.Opaque is ""
fmt.Printf("u.User is %#v\n", u.User)
// u.User is &url.Userinfo{username:"admin", password:"passwd", passwordSet:true}
fmt.Printf("u.Host is %#v\n", u.Host) // u.Host is "www.baidu.com:80"
fmt.Printf("u.Path is %#v\n", u.Path) // u.Path is "/search"
fmt.Printf("u.RawPath is %#v\n", u.RawPath) // u.RawPath is ""
fmt.Printf("u.ForceQuery is %#v\n", u.ForceQuery) // u.ForceQuery is false
fmt.Printf("u.RawQuery is %#v\n", u.RawQuery) // u.RawQuery is "mq=test"
fmt.Printf("u.Fragment is %#v\n", u.Fragment) // u.Fragment is "12345"
}
ParseRequestURI
ParseRequestURI 函数解析 rawurl 为一个 URL 结构体,本函数会假设 rawurl 是在一个 HTTP 请求里,因此会假设该参数是一个绝对 URL 或者绝对路径,并会假设该 URL 没有 #fragment 后缀。
golang
func ParseRequestURI(rawurl string) (url *URL, err error)
func main() {
urlString := "https://admin:passwd@www.baidu.com:80/search?mq=test#12345"
u, err := url.ParseRequestURI(urlString)
if err != nil {
fmt.Println("parse error ", err)
}
fmt.Printf("u.Fragment is %#v\n", u.Fragment) // u.Fragment is ""
}
判断是否是绝对路径func (*URL) IsAbs
golang
func (u *URL) IsAbs() bool //绝对路径返回true
func (*URL) Query
Query 方法解析 RawQuery 字段并返回其表示的 Values 类型键值对。
golang
func (u *URL) Query() Values
//map[mq:[test]]
func (*URL) RequestURI
RequestURI 方法返回编码好的 path?query 或 opaque?query 字符串,用在 HTTP 请求里。
golang
func (u *URL) RequestURI() string
///search?mq=test
func (*URL) String
String 将 URL 重构为一个合法 URL 字符串。
golang
func (u *URL) String() string
//https://admin:passwd@www.baidu.com:80/search?mq=test#12345
func (*URL) Parse
Parse 方法以 u 为上下文来解析一个 URL , ref 可以是绝对或相对 URL。本方法解析失败会返回 nil , err ;否则返回结果和 ResolveReference 一致。
golang
func main() {
urlString := "https://www.baidu.com/search?mq=rabbitmq&queue=people#12345"
u, err := url.Parse(urlString)
if err != nil {
fmt.Println("parse error ", err)
}
fmt.Printf("u.IsAbs is %#v\n", u.IsAbs()) // u.IsAbs is true
fmt.Printf("u.Query is %#v\n", u.Query())
// u.Query is url.Values{"mq":[]string{"rabbitmq"}, "queue":[]string{"people"}}
fmt.Printf("u.RequestURI is %#v\n", u.RequestURI())
// u.RequestURI is "/search?mq=rabbitmq&queue=people"
fmt.Printf("u.String is %#v\n", u.String())
// u.String is "https://www.baidu.com/search?mq=rabbitmq&queue=people#12345"
}
func (*URL) ResolveReference
本方法根据一个绝对 URI 将一个 URI 补全为一个绝对 URI 。参数 ref 可以是绝对 URI 或者相对 URI 。 ResolveReference 总是返回一个新的 URL 实例,即使该实例和 u 或者 ref完全一样。如果 ref 是绝对 URI ,本方法会忽略参照 URI 并返回 ref 的一个拷贝。
golang
func (u *URL) ResolveReference(ref *URL) *URL
type Values
Values 将建映射到值的列表。它一般用于查询的参数和表单的属性。不同于 http.Header 这个字典类型, Values 的键是大小写敏感的。
golang
type Values map[string][]string
func ParseQuery
ParseQuery 函数解析一个 URL 编码的查询字符串,并返回可以表示该查询的 Values 类型的字典。本函数总是返回一个包含了所有合法查询参数的非 nil 字典, err 用来描述解码时遇到的(如果有)第一个错误。
golang
func ParseQuery(query string) (m Values, err error)
func main() {
rawUrl := "mq=rabbitmq&queue=people"
v, err := url.ParseQuery(rawUrl)
if err != nil {
fmt.Println("ParseQuery error ", err)
}
fmt.Printf("v type is %T, v is %#v\n", v, v)
// v type is url.Values, v is url.Values{"mq":[]string{"rabbitmq"}, "queue":[]string{"people"}}
// 等价于下面的方法
urlString := "https://www.baidu.com/search?mq=rabbitmq&queue=people#12345"
u, _ := url.Parse(urlString)
queryV := u.Query()
fmt.Printf("queryV type is %T, queryV is %#v\n", queryV, queryV)
// queryV type is url.Values, queryV is url.Values{"mq":[]string{"rabbitmq"}, "queue":[]string{"people"}}
}
Get、Set、Add、Del、 Encode
golang
//Get 会获取 key 对应的值集的第一个值。如果没有对应key的值集会返回空字符串。获取值集请直接用 map 。
func (v Values) Get(key string) string
//Set 方法将 key 对应的值集设为只有 value ,它会替换掉已有的值集。
func (v Values) Set(key, value string)
//Add 将 value 添加到 key 关联的值集里原有的值的后面。
func (v Values) Add(key, value string)
//Del 删除 key 关联的值集
func (v Values) Del(key string)
//Encode 方法将 v 编码为 ur 编码格式("bar=baz&foo=quux"),编码时会以键进行排序
func (v Values) Encode() string
func main() {
rawUrl := "mq=rabbitmq&queue=people"
v, err := url.ParseQuery(rawUrl)
if err != nil {
fmt.Println("ParseQuery error ", err)
}
fmt.Printf("v type is %T, v is %#v\n", v, v)
// v type is url.Values, v is url.Values{"mq":[]string{"rabbitmq"}, "queue":[]string{"people"}}
fmt.Println(v.Get("mq")) // rabbitmq
v.Set("mq", "redis")
fmt.Println(v.Get("mq")) // redis
v.Add("name", "wohu")
fmt.Printf("v is %#v\n", v)
// v is url.Values{"mq":[]string{"redis"}, "name":[]string{"wohu"}, "queue":[]string{"people"}}
fmt.Printf("v.Encode is %#v\n", v.Encode()) // v.Encode is "mq=redis&name=wohu&queue=people"
v.Del("name")
fmt.Printf("v is %#v\n", v)
// v is url.Values{"mq":[]string{"redis"}, "queue":[]string{"people"}}
}
查询转义:QueryEscape、QueryUnescape
QueryEscape
QueryEscape 函数对 s 进行转码使之可以安全的用在 URL 查询里。
golang
func QueryEscape(s string) string
func QueryUnescape
QueryUnescape 函数用于将 QueryEscape 转码的字符串还原。它会把 %AB 改为字节 0xAB ,将 + 改为空格 。如果有某个 % 后面未跟两个十六进制数字,本函数会返回错误。
golang
func QueryUnescape(s string) (string, error)
func main() {
rawUrl := "mq=rabbitmq&queue=people"
stdUrl := url.QueryEscape(rawUrl)
fmt.Printf("stdUrl is %v\n", stdUrl) // stdUrl is mq%3Drabbitmq%26queue%3Dpeople
rawurl, _ := url.QueryUnescape(stdUrl)
fmt.Printf("rawurl is %v\n", rawurl) // rawurl is mq=rabbitmq&queue=people
}