URI的百分號編碼 尤其是特殊字符的編碼

特殊字符一定要注意

URI的百分號編碼
URI的字符類型
URI所允許的字符分作保留與未保留。保留字符是那些具有特殊含義的字符,例如:斜線字符用於URL(或URI)不同部分的分界符;未保留字符沒有這些特殊含義。百分號編碼把保留字符表示爲特殊字符序列。上述情形隨URI與URI的不同版本規格會有輕微的變化。

RFC 3986 section 2.2 保留字符 (2005年1月)
!	*	'	(	)	;	:	@	&	=	+	$	,	/	?	#	[	]
RFC 3986 section 2.3 未保留字符 (2005年1月)
A	B	C	D	E	F	G	H	I	J	K	L	M	N	O	P	Q	R	S	T	U	V	W	X	Y	Z
a	b	c	d	e	f	g	h	i	j	k	l	m	n	o	p	q	r	s	t	u	v	w	x	y	z
0	1	2	3	4	5	6	7	8	9	-	_	.	~	
URI中的其它字符必須用百分號編碼。

保留字符的百分號編碼
如果一個保留字符在特定上下文中具有特殊含義(稱作"reserved purpose") , 且URI中必須使用該字符用於其它目的, 那麼該字符必須百分號編碼。百分號編碼一個保留字符,首先需要把該字符的ASCII的值表示爲兩個16進制的數字,然後在其前面放置轉義字符("%"),置入URI中的相應位置。(對於非ASCII字符, 需要轉換爲UTF-8字節序, 然後每個字節按照上述方式表示.)

例如,"/", 如果用作URI的路徑成分的分界符, 則是具有特殊含義的保留字符. 如果該字符需要出現在URI一個路徑成分的內部, 則三字符序列"%2F"或"%2f"就用於代替原本的"/"出現在該URI路徑成分的內部.

保留字符的百分號編碼
!	#	$	&	'	(	)	*	+	,	/	:	;	=	?	@	[	]
%21	%23	%24	%26	%27	%28	%29	%2A	%2B	%2C	%2F	%3A	%3B	%3D	%3F	%40	%5B	%5D
在特定上下文中沒有特殊含義的保留字符也可以被百分號編碼,在語義上與不百分號編碼的該字符沒有差別.

在URI的"查詢"成分(?字符後的部分)中, 例如"/"仍然是保留字符但是沒有特殊含義,除非一個特定的URI有其它規定. 該/字符在沒有特殊含義時不需要百分號編碼.

如果保留字符具有特殊含義,那麼該保留字符用百分號編碼的URI與該保留字符僅用其自身表示的URI具有不同的語義。

百分號編碼未保留字符
未保留字符不需要百分號編碼.

兩個URI的差別如果僅在於未保留字符是用百分號編碼還是用字符自身表示,那麼這兩個URI具有等價的語義. 但URI處理器實際上並不總是把二者視作等價[來源請求]. 例如, URI的消費者不應該把"%41"與"A", "%7E"與"~"視作不同, 但是某些URI的消費者就是這麼做了. 爲了最大的互操作性, URI的製造者不應該對未保留字符進行百分號編碼。

對百分號字符的百分號編碼
由於百分號字符("%")表示百分號編碼字節流的存在, 因此百分號字符應該被編碼爲3個字節的序列:"%25",用於URI內部。

任意數據的百分號編碼
大多數URI涉及表示任意數據, 例如IP地址或文件系統路徑作爲URI的成分。

二進數據
1994年發佈的RFC 1738規定[1], URI中的二進制數據應該表示爲8位元組的序列,然後對每個8位元組按照上述方式百分號編碼. 例如,字節值0F (十六進制)應表示爲"%0F", 字節值41(十六進制)應表示爲"A"或"%41". 優先使用未保留字符來表示這些字節值,因爲這使得URL更短.

字符數據
二進數據的百分號編碼過程已經被外推到字符數據,甚至到不適合或未被完全規範的地步. 在WWW初創階段,僅僅處理ASCII字符是否編碼問題,還沒有什麼問題。但隨後發展到對非ASCII字符如何在URI中編碼,缺少標準規範的情況下導致了歧義性的解釋URI的錯誤。

例如, 基於RFC 1738與2396的協議規定,字符數據先要根據某種字符編碼轉換爲字節流,然後再表示爲URI。如果URI不提供是何種字符編碼的提示信息,那麼這個URI難以可靠的解析。

當前標準
2005年1月發佈的RFC 3986,建議所有新的URI必須對未保留字符不加以百分號編碼;其它字符建議先轉換爲UTF-8字節序列, 然後對其字節值使用百分號編碼。此前的URI不受此標準的影響。

非標準的實現
有一些不符合標準的把Unicode字符在URI中表示爲: %uxxxx, 其中xxxx是用4個十六進制數字表示的Unicode的碼位值。任何RFC都沒有這樣的字符表示方法,並且已經被W3C拒絕。第三版的ECMA-262仍然包含函數escape(string)使用這種語法, 但也有函數encodeURI(uri)轉換字符到UTF-8字節序列並用百分號編碼每個字節。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章