在 iOS 程序訪問 HTTP 資源時需要對 URL 進行 Encode,比如像拼出來的 http://unmi.cc?p1=%+&sd f&p2=中文,其中的中文、特殊符號&%和空格都必須進行轉(zhuǎn)譯才能正確訪問。有時候要把url地址作為參數(shù)的值傳給后臺時,也需要對url地址編碼,不然可能會出現(xiàn)后臺獲取的url解析失敗。
在 Java、.net 和 JS 中都有相應(yīng)的 encodeURL 方法可用,在 Objective-C 語言中,你可以試下
- (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc;
來對完整的 URL(帶請求參數(shù)的)進行編碼,比如執(zhí)行下面的代碼:
NSString *url=@"http://unmi.cc?p1=%+&sd &p2=中文";
NSString *encodedValue = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
上面代碼轉(zhuǎn)換出的 encodedValue 是:
http://unmi.cc?p1=%25+&sd%20&p2=%E4%B8%AD%E6%96%87
可見,它不會轉(zhuǎn)換 URL 中的 ?%& 符號,這也正常,因為它肯定分不出哪個 & 是參數(shù)的連接符號還是參數(shù)值,你可以單獨編碼參數(shù),然后在拼接成 URL 之前把屬性參數(shù)值中的 ?%& 等符號分別替換成相應(yīng)的編碼。
或者,您還可以試下另外一個方法來單獨編碼參數(shù)值,然后拼接成完整的 URL:
/* newString = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, origString, NULL, NULL, kCFStringEncodingUTF8); */
CF_EXPORT
CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding);
參考代碼,分別編碼前面的 p1=%+&sd f&p2=中文,兩個參數(shù)的代碼和結(jié)果如下:
NSString *param = @"%+&sd f";
NSString *encodedValue = (NSString*)CFURLCreateStringByAddingPercentEscapes(nil,
(CFStringRef)param, nil,
(CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8);
這樣編碼出來的 encodedValue 為 %25%2B%26sd%20f,對 ?%& 等符號也會編碼的。用上面的代碼對 “中文” 進行編碼的結(jié)果是:%E4%B8%AD%E6%96%87,與前面是一致的。
我實際應(yīng)用時還是這個 CFURLCreateStringByAddingPercentEscapes 方法比較方便。
我們在項目中是使用的 ASIHTTPRequest 組件來訪問 URL 的,在使用 ASIFormDataRequest 時發(fā)出它其中有一個方法:
- (NSString*)encodeURL:(NSString *)string
{
NSString *newString = NSMakeCollectable([(NSString *)CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"),
CFStringConvertNSStringEncodingToEncoding([self stringEncoding])) autorelease]);
if (newString) {
return newString;
}
return @"";
}
看起來它就是個 Objective-C 版的 encodeURL 方法,可是它聲明成了一個實例方法,必須構(gòu)造出 ASIFormDataRequest 實例才能使用它,在它的父類 ASIHTTPRequest 中都無該方法?,F(xiàn)在來試驗一下這個方法的返回值:
ASIFormDataRequest *formDataRequest = [ASIFormDataRequest requestWithURL:nil];
NSString *encodedValue1 = [formDataRequest encodeURL:@"%+&sd f"];
NSString *encodedValue2 = [formDataRequest encodeURL:@"中文"];
得出的 encodedValue1 和 encodedValue2 分別是 %25%2B%26sd%20f 和 %E4%B8%AD%E6%96%87,和前面是一致的,所以你可以用 ASIFormDataRequest 提供的方式來進行 URLEncode,把這個方法提出為一個工具方法即可。