【基础知识】URL

先说说URL到底是怎么回事情。在RFC1738中说明了统一资源定位器(URL)

1 什么是URL:

因特网上的可用资源可以用简单字符串来表示,该文档就是描述了这种字符串的语法和语义。而这些字符串则被称为:“统一资源定位器”(URL)。

2 主要部分:

URL通常被写成如下形式: <方案>:<方案描述部分> 一个URL包含了它使用的方案名称(<方案>), 其后紧跟一个冒号,然后是一个字符串 (<方案描述部分>),这部分的解释由所使用的方案来决定。
方案名称由一串字符组成。小写字母“a”——“z”,数字,字符加号(“+”),句点(“.”) 和连字号(“-”)都可以。为了方便起见,程序在解释URL的时候应该视方案名称中的大写字母和小写字母一样。(例如:视“HTTP”和“http”一样)。


3 url的组成:

3.1  可以url的字符组成。
URL只能用US-ASCII字符编码集中的可显示字符表示。US-ASCII中没有用到十六进制的八位字节80-FF,并且00-1F和7F代表了控制字符。
也就是说:url中只能使用ASCII码中的20-7E。还没完。。。。
有些字符是被认为不安全的:在『和』中间的是实际的字符
① 空格             20      『 』            因为URL在被转录或者被排版或者被 字处理程序处理后其中重要的空格可能被忽略
② 小于大于号       3C 3E   『<』『>』       因为它们被用来作为URL在文本中的分隔符
③ 双引号           22      『"』            因为而在有些系统 中用引号来界定URL
④ 数字符号         12      『#』            因为它在万维网和其他一些系统中 被用来从“片段/锚点”标志符中界定URL
⑤ 百分号           25      『%』            因为它被用来对其他字符进行编码
⑥ 左、右大括号     7B 7D   『{』『}』      
⑦ 左、右中括号     5B 5D   『[』『]』
⑧ 垂直线、反斜杠   5C 7C   『|』『\』
⑨ 音调符号、代字号 5E 7E   『^』『~』
⑩ 重音符           60      『`』            以上这些由于网关和其他传输代理有时会对这些字符进行修改,所以它们也是不安全的。
那么现在的URL中就只剩下:『;/?:@=&$-_.+!*'(),』大小写字母和数字了。。。。但是。。。。
许多URL方案保留了一些字符并赋予特定的含义:它们出现在URL的特定部位并表示特定的含义。字符";","/", "?", ":", "@", "=" 和 "&"可能被某个方案所保留,除此之外没有其他的保留字符。
所以url中完全可以使用的就是『$-_.+!*'(),』字母与数字。还有就是和用作保留目的的保留字符(强调的是保留目的 的 保留字符)

那么除了这些字符串之外的其他字符串怎么办?对它进行编码!

编码有以下规则:
·在URL中只有字母与数字,以及特殊字符“$-_.+!*'(),”和用作保留目的的保留字符可以不进行编码。
·不必进行编码的字符(包括字母与数字)如果出现在URL的特定部位,只要它们不用作保留目的,则可进行编码。
·对某一特定方案用作保留目的 的 保留字符一定不能进行编码。


3.2 url的组成结构

3.2.1通用
直接使用基于IP的协议来定位因特网上的主机的URL方案都使用了如下形式的通用语法来表示特定的方案数据:
//<用户名>:<密码>@<主机>:<端口>/url-路径
可能会省略“<用户名>:<密码>@”,“ :<密码>”,“ :<端口>”,和“/”这些部分的某些或者全部。这些方案的特定数据以双斜线“//”开头来表明它遵从通用因特网方案语法。

■用户名
任意的用户名称。有些方案(例如:ftp)允许使用用户名称的描述。
■密码
任意的密码。如果存在的话,它紧跟在用户名后面并用一个冒号隔开。

·在用户名和密码字段中出现的任何“:”,“@”或者“/”都要进行编码
·空的用户名或者密码不同于没有用户名和密码
·决不能在没有指定用户名的情况下指定密码

■主机:
可以是域名,或者它的以“.”分隔的四组十进制数字集合形式的IP地址

·域名是用“.”分隔的域标志串,域标志以字母或者数字开头和结束,也可能包含“-”字符。最右边的域标志不 能以数字开头,这样就在语法结构上将域名和IP地址区分开来了。


■端口:
大部分方案都给协议指定一个默认的端口。也可以随意指定一个十进制形式的端口

·十进制,并用冒号与主机隔开。如果忽略端口,那么这个冒号也要忽略。

■url路径
定位符的其他部分由方案的特殊数据组成,这些特殊数据被称为“url-路径”。它提供了如何对特定资源进行访问的详细信息。

·注意主机(或端口)与url-路径间的“/”不是url-路径的一部分。


有很多都没听说过的,例如:Gopher+交替视图的URL语法 ...还有一些不常用的,例如NEWS(新闻)...就不写了,说点常用的:

3.2.2 FTP
FTP URL的URL-路径语法如下:
<cwd1>/<cwd2>/.../<cwdN>/<name>;type=<typecode>
这里的<cwd1>到<cwdN>和<name>(可能被编码)都是字符串,<typecode>是字符“a”,“i”和“d”之一。“;type=<typecode>”这一部分可以被省略。<cwdx>和<name>部分可以为空。整个url-路径,包括它和包含用户名,密码,主机及端口的前缀间的分界符“/”都可以被省略。
name或者CWD部分的字符“/”和“;”都是保留字符,必须进行编码。在FTP协议中,这些部分在使用前被解码。特别的是,如果访问一个特定文件的适当FTP命令序列需要发送一个包含“/”的字符串作为CWD或者RETR命令的参数,那么必须对每个“/”都进行编码。


3.2.3 HTTP
HTTP URL 方案是用来标志因特网上使用HTTP(HyperText Transfer Protocol,超文本
传输协议)的可达资源。
HTTP协议在其他的地方进行了详细说明。本文只介绍了HTTP URL的语法。
HTTP URL的形式如下:
http://<host>:<port>/<path>?<searchpart>
其中<host>和<port>已经在3.1节说明过了。如果:<port>部分省略,那么就使用缺省的
端口80。不需要用户名和密码。<path>是一个HTTP选择器,<searchpart>是查询字符串。
<path>,<searchpart>和它前面的“?”都是可选择的。如果<path>和<searchpart>部分
都没有,则“/”也可以省略。
<path>和<searchpart>部分中的“/”,“;”和“?”都是保留字符。“/”字符可以在HTTP
中用来表示层次结构。

 

32.4 MAILTO
mailto URL方案是用来指明一个个体或者服务的因特网邮件地址的。它只代表因特网邮件地址,而不表示任何其它的附加信息。
Mailto URL的形式如下所示:
mailto:<rfc822-addr-spec>
这里的<rfc822-addr-spec>是地址说明(的编码),这在RFC822[6]中进行了详细的说明。在mailto URL中没有保留字。
注意百分符号("%")在RFC822中用得比较普遍,它必须被编码。
不像许多URL,mailto方案不代表可直接访问的数据对象;也没有迹象表面它代表一个对象。它的使用方法不同于MIME中的报文/外部实体类型。


3.2.5 FILES(文件)
文件URL方案被用来指定那些特定主机上的可访问的文件。这个方案和其它大多数方案不一样,因为它并不表示一个在因特网上普遍可访问的资源。
文件URL的形式如下:
file://<host>/<path>
这里的<host>是系统域名的全称,在这个系统中<path>是可访问的,它是形如<directory>/<directory>/.../<name>的层次目录。
例如,一个VMS文件:DISK$USER:[MY.NOTES]NOTE123456.TXT的形式如下:
<URL:file://vms.host.edu/disk$user/my/notes/note12345.txt>
有一种特殊情况,就是<host>可以是字符串“localhost”或者空字符串;它被解释为解释这个URL的主机。
file:///C:/Documen.....  中的///就是这个的例子
文件URL方案是与众不同的,因为它不指定一个因特网协议或者访问这些文件的方法;这样它在主机间网络协议上的效用是有限的。

 


写到这,问题似乎解决了:

按照这些规则对url进行编码:
·在URL中只有字母与数字,以及特殊字符“$-_.+!*'(),”和用作保留目的的保留字符可以不进行编码。
·不必进行编码的字符(包括字母与数字)如果出现在URL的特定部位,只要它们不用作保留目的,则可进行编码。
·对某一特定方案用作保留目的 的 保留字符一定不能进行编码。
其中的保留字符参照各个方案。。。。。。


但是实际情况并不是这样:

windows+jdk6+tomcat6

新建"test.html"和"测试.html"

打开ie访问"http://test.yyun.cn/test.html"正常..

访问"http://test.yyun.cn/测试.html"  HTTP Status 404 - /%E6%B5%8B%E8%AF%95.html

ie--->internet选项--->高级--->关闭"总是以utf-8发送url"

重启ie

访问"http://test.yyun.cn/测试.html" HTTP Status 404 - /²âÊÔ.html

将测试转换成gb2312:%2F%B2%E2%CA%D4

访问"http://test.yyun.cn/测试.html"  返回400

这个文件就是访问不了吗?看看别人是怎么说的吧:

 


===================================================================================================

发信人: HAX (海曦), 信区: WebDevelop
标  题: 应朋友的要求把这篇分析url中文问题的分析贴一下
发信站: 饮水思源 (2002年07月09日02:40:45 星期二), 站内信件

这个问题的原因在于url的中文编码问题和服务器和浏览器的实现问
题,很多地方都会遇到。不仅是IE5.0即使在IE 5.5和IE 6.0,某些特
殊的中文字组合也不行的。

按照uri/url的规范(http://www.ietf.org/rfc/rfc2396.txt),uri
一般只能由一部分ascii字符组成。但是其他字符可以通过escape来
转码。而混乱也来源于此。

首先我们要区分字符和octets(八位字节)。这里有两种映射,一是
从uri字符到八位字节,二是从八位字节到原来的字符。

URI character sequence->octet sequence->original character
sequence

通常这种转换是清晰的,例如“a”被转为八位字节的97(十进制),
而字符序列"%0a",被转为八位字节的10(十进制)。

但是对于某些资源来说有第二种转译,uri的一部分八位字节序列随后
被用于呈现字符序列,“charset”定义了这种映射。例如utf-8编码   
定义了unicode到八位字节的映射。于是情况就复杂了,我们需要了解
到底uri用了哪种charset编码,但是一般的uri语法不能提供这个信息。

浏览器一般简单的根据系统缺省编码发送,例如GB2312。兼容性很好
的utf-8(中文字符被转换为3个八位字节,然后进一步表示为%HH也就
是共9个字节)和最常用的gb2312(中文字符被转为2个八位字节并变
成%HH共6个字节)截然不同,但这还不是最糟糕的情况,因为IE有所
谓“始终以utf-8编码url”的选项。可是资源的获取并非仅仅依靠浏
览器,还要服务器识别这个url并最终映射到真正的磁盘上的物理地址
(于是还牵扯到操作系统的编码问题)。遗憾的是即使是微软的iis在
url的编码识别方面也存在问题,我们不能确切的了解到底web服务器
把浏览器发送的请求所包含的url怎么处理。况且还有文件系统的编码
问题。任何一个环节都可能造成错误。也许详细的web服务器文档会回
答这个问题。而且对于apache和iis,或者其他web服务器,答案可能
截然不同。这个问题在ftp服务上同样甚至更严重的存在着。

通常从经验的角度,多数web server(包括中文IIS)通常按照ansi(
gb2312兼容)的方式(每个中文字为%HH%HH)处理url,这也是很多时
候取消utf-8奏效的原因。但遗憾的是,一个是GBK扩展字符,另外也
许是服务器的实现有bug,或者浏览器的实现有bug?,某些字符组合
(估计主要因为在某个环节,某些中文字符的特定组合的内码高位与
其他扩展拉丁字符冲突,造成解析错误)不能奏效。这时候折衷的办      
法也许是换个中文文件名,或者使用每个中文字后加空格?

总而言之,目前为止,实践上最佳的解决方法是

1. 全部使用US-ASCII字符,即英文文件(汉语拼音?)名。

或者2. 使用完全支持Unicode的操作系统(文件系统)和Web Server
,浏览器端打开utf-8。
                                                           

发信人: HAX (海曦), 信区: WebDevelop
标  题: Re: 关于上文的说明
发信站: 饮水思源 (2002年07月09日02:52:20 星期二), 站内信件

还有,好像用同一个版本的IE 5,但在Win98和Win2000的平台差异也有关系。
这个问题实在太复杂,需要牛人的全面测试。         


发信人: HAX (海曦), 信区: WebDevelop
标  题: Re: 关于上文的说明
发信站: 饮水思源 (2002年07月09日03:06:38 星期二), 站内信件

IIS可能存在缺陷,详细见:
http://www.csdn.net/Develop/article/13%5C13789.shtm

简要的说就是:
IIS接收时,会自动将这个UTF8编码的URL转换为Unicode编码,但是
它有时会错误地丢掉奇数UTF8编码字符串的最后一个字节,所以得到
就会是乱码。

这个问题可能跟这个漏洞有关:
http://www.chinabyte.com/20010717/189341_3.shtml
                                                     

发信人: HAX (海曦), 信区: WebDevelop
标  题: Re: 关于上文的说明
发信站: 饮水思源 (2002年07月09日03:24:13 星期二), 站内信件

刚刚找到一篇文章说明我对这个问题认识太天真
http://www.netpower.com.cn/JISHU/ZHUANLAN/show.asp?num=43
看来真的不是那么容易……
也许只有等到UTF-16大行其道的时候,问题才能彻底解决。

 

总结:按照我现在的认识,这个问题由以下部分组成:

1. URI的规范中没有识别encoding的方案,客户端和服务器端编码的不一致造成无法辨认。但是实际中一般使用UTF-8进行编码,或者遵照HTTP头中的charset-encoding的说明(就像对待post数据的编码一样处理),因此不是决定性的因素。

2. 客户端和服务器端的UTF-8实现可能有bug。

3. 旧的UTF-8规范本身有漏洞,而IIS或其它web服务器软件对此的不当处理导致安全漏洞以及url错误解析问题。

总之,基本上是与JSP无关的。
===================================================================================================

posted @ 2007-05-14 14:30  不写代码好多年  阅读(1106)  评论(0)    收藏  举报