nin*_*alt -2 validation url go
我正在尝试使用Go的标准库验证URL.这是我的代码目前的样子.
import (
"fmt"
"net/url"
)
func isValidURL(tocheck string) bool {
_, err := url.ParseRequestURI(tocheck)
return err == nil
}
func main() {
fmt.Println(isValidURL("google.com")) //returns false, expected true
fmt.Println(isValidURL("www.google.com")) //returns false, expected true
fmt.Println(isValidURL("google")) //returns false, expected false
fmt.Println(isValidURL("/google")) //returns true, expected false
}
Run Code Online (Sandbox Code Playgroud)
尽管前两个应该是真的,但所有三个示例都打印为false.然后我尝试追加https://到不以它们开头的URL的开头,但随后一切都https://aaaa被解析为有效.我该怎么做才能确保它只在URL实际有效时才返回true?
其中大多数是域名.https://aaaa是一个有效的URL./google不是URL,但可以接受,ParseRequestURI因为它也接受绝对路径.
" rawurl仅被解释为绝对URI 或绝对路径 "
当您ParseRequestURI要求对绝对URL或绝对路径进行严格的语法检查时.绝对的路径就是这样/foo/bar.RFC 3986涵盖了什么是非绝对URL .URI的基本语法是这样的.
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
Run Code Online (Sandbox Code Playgroud)
"绝对URL"表示该path部分是绝对路径或空,所以path-abempty或path-absolute更高.http和httpsURL只能是绝对的.foo:bar/baz是相对URL的示例.
这是一个例子.
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
Run Code Online (Sandbox Code Playgroud)
google.com没有scheme,所以它不是一个URL.https://aaaa有一个方案,https并且hier-part,//aaaa,所以它是一个URL.它没有query或fragement,但它们是可选的.
显然这有点宽泛.在现实世界中,您需要缩小您的要求.通常它就像......
ParseRequestURI因为它也可以是一个绝对路径.url.Scheme.这将丢弃绝对路径.url.Host.以及您可能想要做的任何其他检查,以限制您认为有效的URL.
所以你的全面检查可能看起来像......
package main
import (
"fmt"
"net"
"net/url"
"errors"
)
func isValidURL(tocheck string) (bool, error) {
// Check it's an Absolute URL or absolute path
uri, err := url.ParseRequestURI(tocheck)
if err != nil {
return false, err
}
// Check it's an acceptable scheme
switch uri.Scheme {
case "http":
case "https":
default:
return false, errors.New("Invalid scheme")
}
// Check it's a valid domain name
_,err = net.LookupHost(uri.Host)
if err != nil {
return false, err
}
return true, nil
}
func main() {
// False, no scheme
fmt.Println(isValidURL("/google"))
// True, good scheme, good domain
fmt.Println(isValidURL("https://google.com"))
// False, bad domain
fmt.Println(isValidURL("http://halghalghlakdjfl.blarg"))
}
Run Code Online (Sandbox Code Playgroud)