net/url库是Go语言处理URL的核心工具,通过Parse函数将URL字符串解析为*url.URL对象,可访问Scheme、Host、Path、RawQuery和Fragment等组件。使用url.Values处理查询参数,支持Get、Set、Add、Del和Encode方法,实现参数的获取、修改与编码。库自动处理百分号编码,对特殊字符如中文和空格进行解码,同时提供url.PathEscape、url.QueryEscape等函数手动编码路径和查询参数。需注意url.Values为map类型,参数顺序无序,Get仅返回首个值,多值需直接访问切片。此外,可操作User、Fragment等字段,适用于构建API请求、重定向等场景,是安全高效处理URL的“瑞士军刀”。

在Go语言中,处理URL的解析、构建与参数提取,
net/url
net/url
Parse
URL
url.Parse()
*url.URL
package main
import (
"fmt"
"net/url"
"strings"
)
func main() {
rawURL := "https://www.example.com/path/to/resource?name=Go&version=1.20&tags=web,http#section1"
// 1. 解析URL
u, err := url.Parse(rawURL)
if err != nil {
fmt.Println("URL解析失败:", err)
return
}
fmt.Println("--- URL 解析结果 ---")
fmt.Printf("Scheme: %s\n", u.Scheme) // https
fmt.Printf("Host: %s\n", u.Host) // www.example.com
fmt.Printf("Path: %s\n", u.Path) // /path/to/resource
fmt.Printf("RawQuery: %s\n", u.RawQuery) // name=Go&version=1.20&tags=web,http
fmt.Printf("Fragment: %s\n", u.Fragment) // section1
// 2. 处理查询参数
// u.Query() 返回的是 url.Values 类型,它是一个 map[string][]string
queryParams := u.Query()
fmt.Println("\n--- 查询参数处理 ---")
fmt.Printf("获取 'name': %s\n", queryParams.Get("name")) // Go
fmt.Printf("获取 'version': %s\n", queryParams.Get("version")) // 1.20
// 对于有多个值的参数(如tags),Get只会返回第一个,需要直接访问map或使用循环
fmt.Printf("获取 'tags' (Get): %s\n", queryParams.Get("tags")) // web
fmt.Printf("获取 'tags' (直接访问): %v\n", queryParams["tags"]) // [web http]
// 修改或添加参数
queryParams.Set("version", "1.21") // 修改现有参数
queryParams.Add("tags", "api") // 添加一个新值到tags参数,或者新增tags如果不存在
queryParams.Add("newParam", "value") // 添加新参数
queryParams.Del("name") // 删除参数
// 重新构建查询字符串
u.RawQuery = queryParams.Encode()
fmt.Printf("修改后的查询字符串: %s\n", u.RawQuery) // newParam=value&tags=web&tags=http&tags=api&version=1.21
// 3. 构建新的URL
// 我们可以修改URL对象的各个字段,然后用String()方法获取完整的URL
u.Path = "/new/path"
u.Host = "api.example.com"
fmt.Printf("修改后的完整URL: %s\n", u.String()) // https://api.example.com/new/path?newParam=value&tags=web&tags=http&tags=api&version=1.21#section1
// 4. 处理带有编码的URL
encodedURL := "http://example.com/search?q=%E4%BD%A0%E5%A5%BD%20Go%21"
u2, err := url.Parse(encodedURL)
if err != nil {
fmt.Println("URL解析失败:", err)
return
}
fmt.Printf("\n--- 编码URL处理 ---")
fmt.Printf("原始查询: %s\n", u2.RawQuery) // q=%E4%BD%A0%E5%A5%BD%20Go%21
fmt.Printf("解码后的查询参数 'q': %s\n", u2.Query().Get("q")) // 你好 Go!
// 手动编码参数
paramValue := "中文内容 with spaces"
encodedParam := url.QueryEscape(paramValue)
fmt.Printf("手动编码参数 '%s' -> '%s'\n", paramValue, encodedParam) // 中文内容 with spaces -> %E4%B8%AD%E6%96%87%E5%86%85%E5%AE%B9+with+spaces
// 构建带有手动编码参数的URL
newQuery := url.Values{}
newQuery.Add("search", paramValue)
fmt.Printf("使用url.Values构建并编码的查询字符串: %s\n", newQuery.Encode()) // search=%E4%B8%AD%E6%96%87%E5%86%85%E5%AE%B9+with+spaces
}这段代码展示了
net/url
u.Query()
url.Values
map[string][]string
?tag=go&tag=web
Get()
Set()
Add()
Del()
Encode()
在处理URL时,特殊字符一直是个让人头疼的问题。URL规范(RFC 3986)对哪些字符可以直接出现在URL中,哪些需要进行百分号编码(percent-encoding)有严格规定。
net/url
立即学习“go语言免费学习笔记(深入)”;
url.Parse()
http://example.com?name=%E5%BC%A0%E4%B8%89
u.Query().Get("name")
然而,如果URL本身结构不规范,或者包含了非法的百分号编码(比如
%XX
url.Parse()
/
&
=
有时候,我们可能需要手动处理URL的某些部分,例如,从一个非标准的源获取到一段已经被部分解码的路径,或者需要构建一个包含特殊字符的路径。这时,
url.PathEscape()
url.QueryEscape()
url.PathUnescape()
url.QueryUnescape()
// 示例:手动编码和解码
pathSegment := "我的文件/test.txt"
encodedPath := url.PathEscape(pathSegment)
fmt.Printf("路径编码: '%s' -> '%s'\n", pathSegment, encodedPath) // 我的文件/test.txt -> %E6%88%91%E7%9A%84%E6%96%87%E4%BB%B6/test.txt
queryValue := "Go 语言 & Web 开发"
encodedQuery := url.QueryEscape(queryValue)
fmt.Printf("查询参数编码: '%s' -> '%s'\n", queryValue, encodedQuery) // Go 语言 & Web 开发 -> Go+%E8%AF%AD%E8%A8%80+%26+Web+%E5%BC%80%E5%8F%91
// 手动解码
decodedPath, _ := url.PathUnescape(encodedPath)
fmt.Printf("路径解码: '%s' -> '%s'\n", encodedPath, decodedPath)
decodedQuery, _ := url.QueryUnescape(encodedQuery)
fmt.Printf("查询参数解码: '%s' -> '%s'\n", encodedQuery, decodedQuery)在使用这些手动函数时,务必清楚你处理的是URL的哪个部分,因为路径和查询参数的编码规则确实有细微差别,比如空格在路径中通常编码为
%20
+
%20
+
url.Values
一个常见的误解是,
queryParams.Get("key")Get()
?tag=go&tag=web&tag=api
queryParams.Get("tag")"go"
map[string][]string
queryParams["tag"]
[]string{"go", "web", "api"}另一个容易被忽视的点是空值。如果URL中有一个参数是
?param=
queryParams.Get("param")""
nil
nil
queryParams.Has("param")再就是
Set()
Add()
Set("key", "value")Add("key", "value")queryParams.Add("tag", "newTag")newTag
tag
queryParams.Set("tag", "singleTag")tag
singleTag
Add
Encode()
最后,一个微妙但重要的点是参数的顺序。
url.Values
map
map
queryParams.Encode()
net/url
net/url
net/url
*url.URL
除了我们已经讨论过的
Path
RawQuery
http
https
ftp
u.Scheme
www.example.com:8080
u.Host
#
#section1
u.Fragment
ftp://user:pass@example.com
u.User
*url.Userinfo
举个例子,如果你需要从一个原始URL生成一个用于API请求的URL,你可能需要修改它的主机和路径,同时保留或修改查询参数:
originalURL := "http://old.example.com/legacy/data?id=123&token=abc"
u, _ := url.Parse(originalURL)
// 修改为新的API端点
u.Scheme = "https"
u.Host = "api.new.example.com"
u.Path = "/v1/resource"
// 保留原始查询参数,并添加一个API版本参数
queryParams := u.Query()
queryParams.Add("api_version", "2023-10-26")
u.RawQuery = queryParams.Encode()
fmt.Printf("转换后的API URL: %s\n", u.String())
// 输出: https://api.new.example.com/v1/resource?api_version=2023-10-26&id=123&token=abc通过这种方式,
net/url
以上就是Golang net/url库URL解析与参数处理的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号