golang net.url 标准库

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
}

福利彩蛋:没有好玩的 API 接口?上百款免费接口等你来,免费 API,免费 API 大全

相关推荐
程序员的开发手册5 分钟前
新手教学系列——慎用Flask-SQLAlchemy慢日志记录
数据库·python·flask·sqlalchemy
虫小宝9 分钟前
如何在Java中实现PDF生成
java·开发语言·pdf
Java4ye9 分钟前
Netty 是如何解析 Redis RESP 协议的——请求篇
后端
菜鸡且互啄691 小时前
在线教育平台,easyexcel使用案例
java·开发语言
八月林城1 小时前
JAVA导出数据库字典到Excel
java·数据库·excel
电饭叔2 小时前
《python程序语言设计》2018版第5章第52题利用turtle绘制sin函数
开发语言·python
weixin_452600692 小时前
如何为老化的汽车铅酸电池充电
开发语言·单片机·安全·汽车·电机·电源模块·充电桩
Java资深爱好者3 小时前
如何在std::map中查找元素
开发语言·c++
YCCX_XFF213 小时前
ImportError: DLL load failed while importing _imaging: 操作系统无法运行 %1
开发语言·python
TiDB_PingCAP4 小时前
国产化新标杆:TiDB 助力广发银行新一代总账系统投产上线
运维·数据库·开源·tidb