使用Go语言的标准包验证URL。

huangapple go评论76阅读模式
英文:

Validate URL with standard package in GO

问题

在Go的标准包中,有没有可以验证URL的函数?

我在初步搜索中没有找到相关的内容,
而且我不想使用正则表达式进行检查。

英文:

Is there any function in a standard package in GO that allows to validate a URL?

I have not found anything on my initial search,
and I would prefer not to resort to regex checking.

答案1

得分: 108

是的,url.ParseRequestURI 如果URL无效、不是绝对URL等等情况下会返回错误,而不是继续解析。url.Parse 几乎可以解析任何内容并返回有效结果。

import "net/url"

...

u, err := url.ParseRequestURI("http://google.com/")
if err != nil {
   panic(err)
}

上面的示例不会失败,但以下示例会失败:

u, err := url.ParseRequestURI("http//google.com")

u, err := url.ParseRequestURI("google.com")

u, err := url.ParseRequestURI("/foo/bar")
英文:

Yep, url.ParseRequestURI returns an error if the URL is not valid, not an absolute url, etc etc. url.Parse returns valid on almost anything...

import "net/url"

...


u, err := url.ParseRequestURI("http://google.com/")
if err != nil {
   panic(err)
}

The above example will not fail, but these will:

u, err := url.ParseRequestURI("http//google.com")

u, err := url.ParseRequestURI("google.com")

u, err := url.ParseRequestURI("/foo/bar")

答案2

得分: 42

接受的答案允许空的http://和相对URL,如/foo/bar。如果你想要更严格的检查,可以使用以下代码来拒绝这些情况:

import "net/url"

func IsUrl(str string) bool {
    u, err := url.Parse(str)
    return err == nil && u.Scheme != "" && u.Host != ""
}

示例:https://play.golang.org/p/JngFarWPF2-

这个答案来源于这个回答:https://stackoverflow.com/a/25747925/744298

英文:

The accepted answer allows empty http:// and relative urls like /foo/bar. If you want a stricter check, this will reject those:

import "net/url"

func IsUrl(str string) bool {
	u, err := url.Parse(str)
	return err == nil && u.Scheme != "" && u.Host != ""
}

Example: https://play.golang.org/p/JngFarWPF2-

Which came from this answer: https://stackoverflow.com/a/25747925/744298

答案3

得分: 8

这帮助我理解了标准库url.Parse方法的工作原理,希望对你们中的一些人也有所帮助。请注意,所有这些值都不会引发错误。

package main

import (
	"fmt"
	"net/url"
)

func main() {
	urls := []string{
		"https",
		"https://",
		"",
		"http://www",
		"http://www.dumpsters.com",
		"https://www.dumpsters.com:443",
		"/testing-path",
		"testing-path",
		"alskjff#?asf//dfas",
	}
	for _, u := range urls {
		val, err := url.Parse(u)
		scheme := val.Scheme
		host := val.Host
		hostname := val.Hostname()
		path := val.Path
		fmt.Println("val        : "+u+" : ", val)
		fmt.Println("error      : "+u+" : ", err)
		fmt.Println("scheme     : "+u+" : ", scheme)
		fmt.Println("host       : "+u+" : ", host)
		fmt.Println("hostname   : "+u+" : ", hostname)
		fmt.Println("path       : "+u+" : ", path)
		fmt.Println()
	}
}

结果:

val        : https :  https
error      : https :  <nil>
scheme     : https :
host       : https :
hostname   : https :
path       : https :  https

val        : https:// :  https:
error      : https:// :  <nil>
scheme     : https:// :  https
host       : https:// :
hostname   : https:// :
path       : https:// :

val        :  :
error      :  :  <nil>
scheme     :  :
host       :  :
hostname   :  :
path       :  :

val        : http://www :  http://www
error      : http://www :  <nil>
scheme     : http://www :  http
host       : http://www :  www
hostname   : http://www :  www
path       : http://www :

val        : http://www.dumpsters.com :  http://www.dumpsters.com
error      : http://www.dumpsters.com :  <nil>
scheme     : http://www.dumpsters.com :  http
host       : http://www.dumpsters.com :  www.dumpsters.com
hostname   : http://www.dumpsters.com :  www.dumpsters.com
path       : http://www.dumpsters.com :

val        : https://www.dumpsters.com:443 :  https://www.dumpsters.com:443
error      : https://www.dumpsters.com:443 :  <nil>
scheme     : https://www.dumpsters.com:443 :  https
host       : https://www.dumpsters.com:443 :  www.dumpsters.com:443
hostname   : https://www.dumpsters.com:443 :  www.dumpsters.com
path       : https://www.dumpsters.com:443 :

val        : /testing-path :  /testing-path
error      : /testing-path :  <nil>
scheme     : /testing-path :
host       : /testing-path :
hostname   : /testing-path :
path       : /testing-path :  /testing-path

val        : testing-path :  testing-path
error      : testing-path :  <nil>
scheme     : testing-path :
host       : testing-path :
hostname   : testing-path :
path       : testing-path :  testing-path

val        : alskjff#?asf//dfas :  alskjff#?asf//dfas
error      : alskjff#?asf//dfas :  <nil>
scheme     : alskjff#?asf//dfas :
host       : alskjff#?asf//dfas :
hostname   : alskjff#?asf//dfas :
path       : alskjff#?asf//dfas :  alskjff
英文:

This helped me understand how the standard library url.Parse method works, hope it helps some of you as well. Notice that all these values never throw an error.

package main

import (
    &quot;fmt&quot;
    &quot;net/url&quot;
)

func main() {
    urls := []string{
	    &quot;https&quot;,
	    &quot;https://&quot;,
	    &quot;&quot;,
	    &quot;http://www&quot;,
	    &quot;http://www.dumpsters.com&quot;,
	    &quot;https://www.dumpsters.com:443&quot;,
	    &quot;/testing-path&quot;,
	    &quot;testing-path&quot;,
	    &quot;alskjff#?asf//dfas&quot;,
    }
    for _, u := range urls {
	    val, err := url.Parse(u)
	    scheme := val.Scheme
	    host := val.Host
	    hostname := val.Hostname()
	    path := val.Path
	    fmt.Println(&quot;val        : &quot;+u+&quot; : &quot;, val)
	    fmt.Println(&quot;error      : &quot;+u+&quot; : &quot;, err)
	    fmt.Println(&quot;scheme     : &quot;+u+&quot; : &quot;, scheme)
	    fmt.Println(&quot;host       : &quot;+u+&quot; : &quot;, host)
	    fmt.Println(&quot;hostname   : &quot;+u+&quot; : &quot;, hostname)
	    fmt.Println(&quot;path       : &quot;+u+&quot; : &quot;, path)
	    fmt.Println()
    }
}

The results

val        : https :  https
error      : https :  &lt;nil&gt;
scheme     : https :
host       : https :
hostname   : https :
path       : https :  https

val        : https:// :  https:
error      : https:// :  &lt;nil&gt;
scheme     : https:// :  https
host       : https:// :
hostname   : https:// :
path       : https:// :

val        :  :
error      :  :  &lt;nil&gt;
scheme     :  :
host       :  :
hostname   :  :
path       :  :

val        : http://www :  http://www
error      : http://www :  &lt;nil&gt;
scheme     : http://www :  http
host       : http://www :  www
hostname   : http://www :  www
path       : http://www :

val        : http://www.dumpsters.com :  http://www.dumpsters.com
error      : http://www.dumpsters.com :  &lt;nil&gt;
scheme     : http://www.dumpsters.com :  http
host       : http://www.dumpsters.com :  www.dumpsters.com
hostname   : http://www.dumpsters.com :  www.dumpsters.com
path       : http://www.dumpsters.com :

val        : https://www.dumpsters.com:443 :  https://www.dumpsters.com:443
error      : https://www.dumpsters.com:443 :  &lt;nil&gt;
scheme     : https://www.dumpsters.com:443 :  https
host       : https://www.dumpsters.com:443 :  www.dumpsters.com:443
hostname   : https://www.dumpsters.com:443 :  www.dumpsters.com
path       : https://www.dumpsters.com:443 :

val        : /testing-path :  /testing-path
error      : /testing-path :  &lt;nil&gt;
scheme     : /testing-path :
host       : /testing-path :
hostname   : /testing-path :
path       : /testing-path :  /testing-path

val        : testing-path :  testing-path
error      : testing-path :  &lt;nil&gt;
scheme     : testing-path :
host       : testing-path :
hostname   : testing-path :
path       : testing-path :  testing-path

val        : alskjff#?asf//dfas :  alskjff#?asf//dfas
error      : alskjff#?asf//dfas :  &lt;nil&gt;
scheme     : alskjff#?asf//dfas :
host       : alskjff#?asf//dfas :
hostname   : alskjff#?asf//dfas :
path       : alskjff#?asf//dfas :  alskjff

答案4

得分: 1

func IsUrl(str string) bool {
	url, err := url.ParseRequestURI(str)
	if err != nil {
		log.Info(err.Error())
		return false
	}

	address := net.ParseIP(url.Host)
	log.Infow("url-info", "host", address)

	if address == nil {
		log.Infow("url-info", "host", url.Host)

		return strings.Contains(url.Host, ".")
	}

	return true
}

func Test_IsAllowUrl(t *testing.T) {
	assert.True(t, IsUrl("http://google.com"))
	assert.True(t, IsUrl("http://w.com/cn"))
	assert.True(t, IsUrl("http://192.158.0.1:90"))
	assert.False(t, IsUrl("http://w"))
	assert.False(t, IsUrl("fsw"))
	assert.False(t, IsUrl("http://192.158.1/1"))
}

最后一个"http:/192.158.1/1"没有通过。也许应该匹配所有允许的域名,但这样会变得太复杂。
https://www.iana.org/domains/root/db

英文:
func IsUrl(str string) bool {
	url, err := url.ParseRequestURI(str)
	if err != nil {
		log.Info(err.Error())
		return false
	}

	address := net.ParseIP(url.Host)
	log.Infow(&quot;url-info&quot;, &quot;host&quot;, address)

	if address == nil {
		log.Infow(&quot;url-info&quot;, &quot;host&quot;, url.Host)

		return  strings.Contains(url.Host, &quot;.&quot;) 
	}

	return true
}
func Test_IsAllowUrl(t *testing.T) {
	assert.True(t, IsUrl(&quot;http://google.com&quot;))
	assert.True(t, IsUrl(&quot;http://w.com/cn&quot;))
	assert.True(t, IsUrl(&quot;http://192.158.0.1:90&quot;))
	assert.False(t, IsUrl(&quot;http://w&quot;))
	assert.False(t, IsUrl(&quot;fsw&quot;))
	assert.False(t, IsUrl(&quot;http://192.158.1/1&quot;))

}

the last "http:/192.158.1/1" not pass. may be should match all allow domains,but will be to complex
https://www.iana.org/domains/root/db

huangapple
  • 本文由 发表于 2015年7月18日 00:41:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/31480710.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定