我试图确保传递给我的go程序的URL有效。但是,我似乎无法解决问题。我以为我可以通过url.Parse
提供它,但这似乎无法完成这项工作。
package main
import (
"fmt"
"net/url"
)
func main() {
url, err := url.Parse("http:::/not.valid/a//a??a?b=&&c#hi")
if err != nil {
panic(err)
}
fmt.Println("It's valid!", url.String())
}
我可以使用filter_var的任何内容吗?
答案 0 :(得分:4)
您可以检查您的网址是否包含Scheme,Host和/或Path。
如果检查返回的URL,您可以看到无效部分被插入到不透明数据部分(因此在某种意义上,它是有效的。)
url.URL{Scheme:"http", Opaque:"::/not.valid/a//a", Host:"", Path:"", RawQuery:"?a?b=&&c", Fragment:"hi"}
如果您解析网址并且没有方案,主机和路径,您可能会认为它无效。 (虽然没有路径的主机通常没问题,因为它暗示/
,所以你需要检查它)
u, err := url.Parse("http:::/not.valid/a//a??a?b=&&c#hi")
if err != nil {
log.Fatal(err)
}
if u.Scheme == "" || u.Host == "" || u.Path == "" {
log.Fatal("invalid URL")
}
答案 1 :(得分:1)
如果viaRequest
为真,url.Parse()函数将返回错误,这意味着假定URL是通过HTTP请求到达的。
直接致电url.Parse()
时并非如此:请参阅source code。
if url, err = parse(u, false); err != nil {
return nil, err
}
如果func parse(rawurl string, viaRequest bool) (url *URL, err error) {
为真,则err
仅返回viaRequest
。
这就是为什么直接使用url.Parse()
时从未发现任何错误。
在后一种情况下,如果没有返回err
,您可以查看返回的URL
object字段。
空的url.Scheme
或url.Path
不是预期的,表示错误。
答案 2 :(得分:0)
试试这个包go validator并且你想要的是IsURL功能。(你也可以使用regexp包)
package main
import (
"fmt"
"regexp"
)
const URL string = `^((ftp|http|https):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(((([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)\.)?)?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?)|localhost)(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`
func Matches(str, pattern string) bool {
match, _ := regexp.MatchString(pattern, str)
return match
}
func main() {
u1 := "http:::/not.valid/a//a??a?b=&&c#hi"
u2 := "http://golang.fastrl.com"
func(us ...string) {
for _, u := range us {
fmt.Println(Matches(u, URL))
}
}(u1, u2)
}