10 go
我正在尝试在 Go 中解析 URL 并从 URL 中获取主机和方案。但是,在使用端口而不使用方案解析 URL 时,我得到了意外的结果。
u, err := url.ParseRequestURI("hello.com:81")
fmt.Println("host :",u.Host)
fmt.Println("scheme :",u.Scheme)
Run Code Online (Sandbox Code Playgroud)
我得到了意想不到的结果
host :
scheme: hello.com
Run Code Online (Sandbox Code Playgroud)
我想要这个
host : hello.com:80
scheme:
Run Code Online (Sandbox Code Playgroud)
Yur*_*lov 11
如果您需要处理仅包含主机和端口(没有方案和其他参数)的 URL,您可以使用以下代码:
host, port, err := net.SplitHostPort("hello.com:81")
fmt.Println("host:", host, "port:", port, "err:", err)
// output: host: hello.com port: 81 err <nil>
Run Code Online (Sandbox Code Playgroud)
注意SplitHostPort()不适合解析标准 URL(符合[scheme:][//[userinfo@]host][/]path[?query][#fragment])
根据 go doc,表示的一般 url 形式为:
[scheme:][//[userinfo@]host][/]path[?query][#fragment]
Run Code Online (Sandbox Code Playgroud)
方案后不以斜杠开头的 URL 被解释为:
scheme:opaque[?query][#fragment]
Run Code Online (Sandbox Code Playgroud)
您的 URL 将被解析为第二种格式。
您可以使用此方法来获得您期望的结果。在函数中,如果 URL 中没有 schema,我们添加它,然后再次解析它以获得预期结果。
func parseRawURL(rawurl string) (domain string, scheme string, err error) {
u, err := url.ParseRequestURI(rawurl)
if err != nil || u.Host == "" {
u, repErr := url.ParseRequestURI("https://" + rawurl)
if repErr != nil {
fmt.Printf("Could not parse raw url: %s, error: %v", rawurl, err)
return
}
domain = u.Host
err = nil
return
}
domain = u.Host
scheme = u.Scheme
return
}
Run Code Online (Sandbox Code Playgroud)
你可以在go游乐场尝试一下