哪些字符使url无效?
哪些字符使url无效?
这些有效的url?
example.com/file[/].html
-
http://example.com/file[/].html
通常, RFC 3986 (参见第2章:字符 )定义的URI可能包含以下任何字符:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=`.
任何其他字符需要使用百分号编码( %
hh
)进行编码。 URI的每个部分都有进一步限制,哪些字符需要用百分比编码的词表示。
要添加一些说明并直接解决上述问题,有几个类别的字符会导致URL和URI的问题。
有一些字符是不允许的,不应该出现在URL / URI,保留字符(如下所述)和其他字符,在某些情况下可能会导致问题,但被标记为“不明智”或“不安全”。 RFC-1738 (URL)和RFC-2396 (URI)明确地解释了字符限制的原因。 注意这些明确的细节存在,但在新的RFC-3986 (更新到RFC-1738)中被隐藏。
排除在URI语法中不允许使用的US-ASCII字符:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal> space = <US-ASCII coded character 20 hexadecimal> delims = "<" | ">" | "#" | "%" | <">
不明智的字符列表是允许的,但可能会导致问题:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
以下字符在查询组件中保留,在URI / URL中具有特殊含义:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
上面的“保留”语法类是指在URI内允许使用的那些字符,但在通用URI语法的特定组件中可能不允许使用这些字符。 “保留”集中的字符在所有上下文中都不保留 。 例如,主机名可以包含一个可选的用户名,所以它可能类似ftp://user@hostname/
,其中“@”字符具有特殊含义。
下面是一个具有无效和不明智的字符(例如'$','[',']')的URL的例子,并且应该被正确地编码:
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
URIs / URL的一些字符限制是依赖于编程语言的。 例如,“|” (0x7C)字符虽然只在URI规范中标记为“不明智”,但会在Java java.net.URI构造函数中引发URISyntaxException ,所以像http://api.google.com/q?exp=a|b
这样的URL是如果将Java与URI对象实例一起使用,则不得将其编码为http://api.google.com/q?exp=a%7Cb
。
现有的大多数答案是不切实际的,因为他们完全忽略了地址的真实使用情况,例如:
好的,根据RFC 3986 ,这样的地址不是URI(因此URL不是URL,因为URL 是一种URItypes )。 如果我们认为自己遵守现有的IETF标准的术语,那么我们应该正确地将它们称为RFC 3987中定义的IRI(国际化的资源标识符),它们在技术上不是URI,而是可以简单地通过百分比编码来转换为URI IRI中的-ASCII字符。 然而,普通人从来没有听说过IRI,只是简单地调用这些URI或URL(事实上,目前正在开展一项WHATWG工作来创build一个新的更广泛的URL规范,将所有“URI”和“IRI”简单地归类为“URL”与在现实世界中使用这些术语的现代)。
假设我们想要立即采用URL的这个含义(这与IETF规范相悖,但与日常使用相一致)。 在这种情况下,哪些字符在URL中有效?
首先,我们有两种types的RFC 3986 保留字符 :
-
:/?#[]@
,它们是RFC 3986中定义的URI的通用语法的一部分 -
!$&'()*+,;=
,它们不是RFC通用语法的一部分,但是被保留用作特定URIscheme的语法组件。 例如,分号和逗号用作数据URI语法的一部分,&
和=
被用作查询string中普遍存在的?foo=bar&qux=baz
格式的一部分(RFC 3986 未指定)。
上面的任何保留字符都可以合法地用在没有编码的URI中,既可以用于其语法目的,也可以用作某些地方数据中的文字字符,这些字符不能被误解为用于其语法目的的字符。 (例如,尽pipe/
在URL中具有语法含义,但是您可以在查询string中使用该string进行未编码,因为它在查询string中没有含义。)
RFC 3986还规定了一些未经保留的字符,它们总是可以用来简单地表示没有任何编码的数据:
-
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
最后,百分号编码允许%
字符本身。
只留下禁止出现在URL中的以下ASCII字符:
- 控制字符(字符0-1F和7F),包括换行符,制表符和回车符。
-
"<>\^`{|}
ASCII中的其他每个字符都可以在URL中合法地显示。
然后,RFC 3987使用以下Unicode字符范围扩展了这些未预留字符集:
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD / %xD0000-DFFFD / %xE1000-EFFFD
但是鉴于最新的Unicode 块定义 ,这些块select显得怪异和随意。 这可能是因为自从RFC 3987写成以来,这些块已经被添加到十年了。 WhatWG正在进行的规范有一个更慷慨的名单 :
U + 00A0至U + D7FF,U + E000至U + FDCF,U + FDF0至U + FFFD,U + 10000至U + 1FFFD,U + 20000至U + 2FFFD,U + 30000至U + 3FFFD,U + U + 50000到U + 5FFFD,U + 60000到U + 6FFFD,U + 70000到U + 7FFFD,U + 80000到U + 8FFFD,U + 90000到U + 9FFFD,U + A0000到U + U + F0000到U + FFFFD,U + F0000到U + BFFFD,U + C0000到U + CFFFD,U + D0000到U + DFFFD,U + E0000到U + EFFFF,U + F0000到U + 10FFFD
当然,应该注意的是,只要知道哪些字符可以合法地出现在URL中就不足以识别某个给定的string是否是合法的URL,因为某些字符在URL的特定部分中只是合法的。 例如,保留字符[
和]
在http:// [1080 :: 8:800:200C:417A] / foo之类的URL中作为IPv6文本主机的一部分是合法的,但在任何其他上下文中都不合法,所以OP的http://example.com/file[/].html
的例子是非法的。
在您的补充问题中,您询问www.example.com/file[/].html
是否为有效的url。
该URL无效,因为URL是一种URItypes,而有效的URI必须具有类似http:
的scheme(请参阅RFC 3986 )。
如果您打算询问http://www.example.com/file[/].html
是否为有效的url,那么答案仍然是否定的,因为方括号字符在那里是无效的。
方括号字符以这种格式保留为URL: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(即IPv6文字而不是主机名)
如果您想充分了解问题,请仔细阅读RFC 3986。
在RFC 3986中定义了可以在URI中使用的所有有效字符( URL是一种URI )。
所有其他字符都可以在URL中使用,只要它们首先是“URL编码”。 这涉及到更改特定“代码”的无效字符(通常以百分号(%)和hex数字的forms)。
这个链接, HTMLurl编码参考 ,包含无效字符的编码列表。
一些Unicode字符范围是有效的HTML5 ,尽pipe使用它们可能不是一个好主意。
例如, href
文档说http://www.w3.org/TR/html5/links.html#attr-hyperlink-href :
a和area元素上的href属性的值必须是可能被空格包围的有效URL。
然后,“有效的URL”的定义指向http://url.spec.whatwg.org/ ,它的目的是:
将RFC 3986和RFC 3987与当前的实现alignment,并在这个过程中将其废弃。
该文件将URL代码点定义为:
ASCII字母数字“!”,“$”,“&”,“'”,“(”,“)”,“*”,“+”,“,”,“ – ”,“。”,“/” ,“+”,“+”,“+”,“+”,“+”, U + U000000至U + 1FFFD,U + 20000至U + 2FFFD,U + 30000至U + 3FFFD,U + 40000至U + 4FFFD,U + 50000至U + 5FFFD,U + 60000到U + 6FFFD,U + 70000到U + 7FFFD,U + 80000到U + 8FFFD,U + 90000到U + 9FFFD,U + A0000到U + AFFFD,U + B0000到U + BFFFD,U +到U + CFFFD,U + D0000到U + DFFFD,U + E1000到U + EFFFD,U + F0000到U + FFFFD,U + 100000到U + 10FFFD。
然后在声明中使用术语“URL代码点”:
如果c不是一个URL代码点而不是“%”,则parsing错误。
在几个部分的parsingalgorithm中,包括模式,权限,相对path,查询和片段状态:所以基本上是整个URL。
另外,validation器http://validator.w3.org/传递像;"你好"
这样的URL,并且不传递带有空格"ab"
字符的URL
当然,正如斯蒂芬·C所提到的,这不仅仅是关于字符,而且关于上下文:你必须理解整个algorithm。 但是,由于在algorithm的关键点上使用了“URL代码点”类,因此它可以很好地了解您可以使用或不使用的内容。
另请参阅: URL中的Unicode字符
不是真正的答案你的问题,但validationurl是真的是一个严重的皮塔饼你可能是更好的validation域名和离开查询部分的url。 那是我的经验。 您也可以使用ping命令来查看url是否有效,但是对于这样一个简单的任务可能太多了。
正则expression式来检测url是丰富的,谷歌它:)
我需要select字符来拆分string中的url,所以我决定创build一个在我自己的URL中找不到的字符列表:
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" >>> from string import printable >>> ''.join(set(printable).difference(set(allowed))) '`" <\x0b\n\r\x0c\\\t{^}|>'
所以,可能的select是换行符,制表符,空格,反斜杠和"<>{}^|
我想我会用空格或换行符:)
使用urlencode允许您的URL中的任意字符。
我想出了一对PHP的正则expression式,将文本中的URL转换为锚标签。 (首先它将所有www。urls转换为http://,然后用https://将所有url转换为href = … html链接
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>', preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string) );