英文:
Ensure a URI is valid
问题
我正在尝试确保传递给我的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的东西可以使用?
英文:
I'm trying to ensure that URLs passed to my go program are valid. However, I can't seem to work out how to. I thought I could just feed it through url.Parse
, but that doesn't seem to do the job.
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())
}
Is there anything along the lines of filter_var I can use?
答案1
得分: 13
您可以检查您的URL是否具有Scheme、Host和/或Path。
如果您检查返回的URL,您会发现无效的部分被插入到不透明数据部分中(从某种意义上说,它是有效的)。
url.URL{Scheme:"http", Opaque:"::/not.valid/a//a", Host:"", Path:"", RawQuery:"?a?b=&c", Fragment:"hi"}
如果解析URL时没有Scheme、Host和Path,您可以假设它是无效的。(尽管没有Path的Host通常是可以的,因为它暗示着/
,所以您需要检查这一点)
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")
}
英文:
You can check that your URL has a Scheme, Host, and/or a Path.
If you inspect the URL returned, you can see that the invalid part is inserted into the Opaque data section (so in a sense, it is valid).
url.URL{Scheme:"http", Opaque:"::/not.valid/a//a", Host:"", Path:"", RawQuery:"?a?b=&&c", Fragment:"hi"}
If you parse a URL and don't have a Scheme, Host and Path you can probably assume it's not valid. (though a host without a path is often OK, since it implies /
, so you need to check for that)
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")
}
答案2
得分: 2
尝试使用这个包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)
}
英文:
have a try of this package go validator and the IsURL func is what you want.(you can use regexp package as well)
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)
}
答案3
得分: 1
url.Parse() 函数主要在 viaRequest
为 true 时返回错误,这意味着如果假设 URL 是通过 HTTP 请求到达的情况下。但是当直接调用 url.Parse()
时,情况并非如此:请参考 源代码。
if url, err = parse(u, false); err != nil {
return nil, err
}
而且 func parse(rawurl string, viaRequest bool) (url *URL, err error) {
只有在 viaRequest
为 true 时才返回 err
。
这就是为什么直接使用 url.Parse()
时你永远不会看到任何错误。
在后一种情况下,即从未返回任何 err
的情况下,你可以检查返回的 URL
对象 的字段。空的 url.Scheme
或者不是预期的 url.Path
都可能表示错误。
英文:
The url.Parse() function will return an error mainly if viaRequest
is true, meaning if the URL is assumed to have arrived via an HTTP request.
Which is not the case when you call url.Parse()
directly: see the source code.
if url, err = parse(u, false); err != nil {
return nil, err
}
And func parse(rawurl string, viaRequest bool) (url *URL, err error) {
only returns err
if viaRequest
is true.
That is why you never see any error when using url.Parse()
directly.
In that latter case, where no err
is ever returned, you can check the fields of the URL
object returned.
An empty url.Scheme
, or an url.Path
which isn't the one expected would indicate an error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论