确保URI有效

时间:2014-09-09 14:45:49

标签: validation url go

我试图确保传递给我的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())
}

playground

我可以使用filter_var的任何内容吗?

3 个答案:

答案 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.Schemeurl.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)
}