URL 语法http URL 方案最初由 RFC 1738 定义(实际上,在之前的 RFC 1630也有涉及),而在 http URL 方案被重新定义之前,整个 URL 语法就已经由扩展了几次 以适应发展的规范进化为一套 统一资源标识符(Uniform Resource Identifiers 即 URIs)。 对于 URLs 如何拼装,各部分如何分隔有一套语法。例如:"://"分隔方案和主机部分。主机同路径片段部分由"/" 分隔,而查询部分紧跟在"?"之后。这意味着有些字符为语法保留。有些为整个URIs保留,而有些则被特定方案保留。 所有出现在不应出现位置的 保留符(例如路径片段——以文件名为例——可能包含"?")必须被URL 编码。 URL 编码将字符转变成对 URL 解析无意义的无害形式。它将字符转化成为一种特定字符编码的字节序列,然后将字 节转换为16进制形式,并将其前面加上"%"。问号的 URL 编码形式为"%3F"。 我们可以将指向 "to_be_or_not_to_be?.jpg"图片的 URL 写成:"http://example.com/to_be_or_not_to_be%3F.jpg",这样就没有人会认为这儿可能由一个查询部分了。 现今多数浏览器显示 URLs 前都会对其解码(将百分号编码字节转回其原本字符),并在获取其网络资源的时候重新 编码。这样一来,很多用户从未意识到编码的存在。 另一方面,网页作者,开发者必须明确认识到这一点,因为这里存在着很多陷阱。 URL常见陷阱如果你正和URL打交道,了解下能够避免的常见陷阱绝对是值得的。现在我们给大家介绍下不仅限于此的一些 常见陷阱。 使用哪类字符编码?URL编码规范并没有定义使用何种字符编码形式去编码字节。一般的ASCII字母数字字符并不需要转义,但是ASCII 之外的保留字需要(例如法语单词“nœud”中的"œ")。我们必须提出疑问,应该使用哪类字符编码来编码URL字节。 当然如果只有Unicode的话,这个世界就会清净很多。因为每个字符都包含其中,但是它只是一个集合,或者说是列 表如果你愿意,它本身并不是一中编码。Unicode可以使用多种方式进行编码,譬如UTF-8或者UTF-16(也有其 它格式),但是问题并没有解决:我们应该使用哪类字符来编码URL(通常也指URI)。 标准并没有定义一个URI应该以何种方式指定其编码,所以其必须从环境信息中进行推导。对于HTTP URL,它可以 是HTML页面的编码格式,或HTTP头的。这通常会让人迷惑,也是许多错误的根源。事实上,最新版的URI标准 定 义了新的URI scheme将采用UTF-8,host(甚至已有的scheme)也使用UTF-8,这让我更加怀疑:难道host和 path真的可以使用不同的编码方式? 每一部分的保留字都是不同。是的,他们是,是的,他们,是的,他们是。。。 对于一个httpd连接,路径片段部分中的空格被编码为"%20"(不,完全没有"+"),而“+”字符在路径片段部分可以 保持不编码。 现在,在查询部分,一个空格可能会被编码为“+”(为了向后兼容:不要试图在URI标准去搜索他)或者“%20”, 当作为“+”字符(作为个统配符的结果)会被编译为“%2B”。 这意味着“blue+light blue”字串,如果在路径部分或者查询部分,将会有不同的编码。比如得到"http://example.com/blue+light%20blue?blue%2Blight+blue"这样的编码形式,这样我们不需从语法上 分析url结构,就可以推导这个url的整个结构是可能 考虑如下组装URL的Java代码片段
编码URL并不是为了转义保留字而进行的简单字符迭代,我们需要确切的知道哪个URL部份有哪些保留字,而有 针对性的进行编码。 这也意味着URL重写过滤器如果不考虑合适的编码细节而对URL直接进行分段转换通常是有问题的。对URL进行 编码而不考虑具体的分段规则是不切实际的。 保留字不是你想象的那样大多数人不知道"+"在路径部分是被允许的并且特指正号而不是空格。其他类似的有:
这样下面的地址虽然看起来有点混乱:"http://example.com/:@-._~!$&'()*+,=;:@-._~!$&'()*+,=:@-._ ~!$&'()*+,==?/?:@-._~!$'()*+,;=/?:@-._~!$'()*+,;==#/?:@-._~!$&'()*+,;=" 按照上面的规则,其实上是一个合法的地址。 不用奇怪,上面路径可以被解析为:
|