根據(jù)RFC 2396標(biāo)準(zhǔn),有些符號(hào)在URI中是不能直接傳遞的,如果要在URI中傳遞這些特殊符號(hào),那么就要使用他們的編碼,編碼的格式為百分比編碼:%加字符的ASCII碼啃擦,即一個(gè)百分號(hào)%,后面跟對(duì)應(yīng)字符的ASCII(16進(jìn)制)碼值饿悬。例如 空格的編碼值是"%20"令蛉。
RFC 2396標(biāo)準(zhǔn)
允許的字符
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
根據(jù)RFC規(guī)范,URI中只可以包含以下特殊字符:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
注意狡恬,這個(gè)列表沒(méi)有說(shuō)明這些字符在URI中的位置珠叔。任何其他字符都需要用百分比編碼。URI的每個(gè)部分都對(duì)需要用百分比編碼的字表示哪些字符有進(jìn)一步的限制弟劲。
保留字符
-
/?#[]@
這是RFC 3986中定義的URI的泛型語(yǔ)法的一部分 -
!$&'()*+,;=
保留用于特定URI方案的語(yǔ)法組件 -
%
用于轉(zhuǎn)義字符的編碼
不需要任何編碼的字符
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
RFC3986還指定了一些亞細(xì)亞字符祷安,這些字符總是可以簡(jiǎn)單地用于表示數(shù)據(jù),而不需要進(jìn)行任何編碼兔乞,而這些字符也正好是允許的字符除去保留字符汇鞭。因此原則上,除了這些字符之外的字符都需要進(jìn)行百分比轉(zhuǎn)義庸追。
禁止出現(xiàn)在URL中的字符
只剩下以下ASCII字符:禁出現(xiàn)在URL中:
- 控制字符(chars0-1F和7F)霍骄,包括
新行
、選項(xiàng)卡
和回車(chē)
淡溯。 - "<>^`{|}
因此需要轉(zhuǎn)義的字符包括保留字符和禁止出現(xiàn)在URL的字符:
?!@#$^&%*+,:;='\"`<>()[]{}/\\|空格
// 來(lái)自網(wǎng)絡(luò)读整,個(gè)人觀點(diǎn),這個(gè)是不全的咱娶,并沒(méi)有包括控制字符米间,但是由于控制字符在
iOS中實(shí)現(xiàn)方案
/// 將除了不需要任何編碼的字符之外所有的字符進(jìn)行轉(zhuǎn)義
+ (NSString *)encodedContentString:(NSString *)str {
NSString *charactersToEscape = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
NSCharacterSet *allowedCharacters = [NSCharacterSet characterSetWithCharactersInString:charactersToEscape];
return [str stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
}
/// 這種方案,由于沒(méi)有將控制字符進(jìn)行轉(zhuǎn)義膘侮,是不準(zhǔn)確的(個(gè)人觀點(diǎn))
+ (NSString *)encodedContentString:(NSString *)str {
NSString *charactersToEscape = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\| ";
NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet];
return [str stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
}