iOS URL編碼和URL拼接(如含中文等特殊符號).md

  • URL編碼默認使用的字符集是US-ASCII.對于非ASCII字符, 需要使用ASCII字符集的超級進行編碼.
  • URL中只允許包含4種字符:
英文字符 : a-zA-Z
數(shù)字: 0-9
-_.~ 4個特殊字符.
保留字符: ! * ' ( ) ; : @ & = + $ , / ? # [ ]

URL編碼使用%其后跟隨兩位(中文是三位)的十六進制數(shù)來替換非ASCII字符,
不能在URL中包含任何非ASCII字符, 如中文字符等.

基本的NSURL

NSString *urlString = @"https://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlString];

但是, 若urlString中含有中文等非URL允許的字符時, 創(chuàng)建的NSURL對象為nil.

iOS 7之后: stringByAddingPercentEncodingWithAllowedCharacters

NSString *latestUrl = @"https://www.baidu.com?name=小明&age=20";

latestUrl = [[latestUrl copy] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

///https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20

NSString *originUrlString = @"https://www.baidu.com/百度?name=小明&age=20";
NSString *encode_fragment = [[originUrlString copy] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSCharacterSet *encode_fragment_invertedSet = [NSCharacterSet URLQueryAllowedCharacterSet].invertedSet;
NSString *encode_fragment_invertedString = [[originUrlString copy] stringByAddingPercentEncodingWithAllowedCharacters:encode_fragment_invertedSet];
/**
 encode_fragment:
 https://www.baidu.com/%E7%99%BE%E5%BA%A6?name=%E5%B0%8F%E6%98%8E&age=20
 
 encode_fragment_invertedString
 %68%74%74%70%73%3A%2F%2F%77%77%77%2E%62%61%69%64%75%2E%63%6F%6D%2F%E7%99%BE%E5%BA%A6%3F%6E%61%6D%65%3D%E5%B0%8F%E6%98%8E%26%61%67%65%3D%32%30
 */

/**

 URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}

 URLHostAllowedCharacterSet      "#%/<>?@\^`{|}

 URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}

 URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}

 URLQueryAllowedCharacterSet     "#%<>[\]^`{|}

 URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

 */

///自定義的字符集. 如(帶空格): [NSCharacterSet characterSetWithCharactersInString:@"#%/!*'\"();:@&=+$,[]? "]

NSString *latestUrl_2 = @"https://www.baidu.com?name=小明&age=20";

NSCharacterSet *defaultCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"?&=/ "];

if (defaultCharacterSet) {

    NSString *latestUrl_2_defaultAllow = [[latestUrl_2 copy] stringByAddingPercentEncodingWithAllowedCharacters:defaultCharacterSet];

    /**

     %68%74%74%70%73%3A//%77%77%77%2E%62%61%69%64%75%2E%63%6F%6D?%6E%61%6D%65=%E5%B0%8F%E6%98%8E&%61%67%65=%32%30

     可以看出除了?&=/ ,其他字符都被編碼了.

     */



    //invertSet

    NSCharacterSet *invertCharacterSet = defaultCharacterSet.invertedSet;

    latestUrl_2 = [[latestUrl_2 copy] stringByAddingPercentEncodingWithAllowedCharacters:invertCharacterSet];

    /**

     https:%2F%2Fwww.baidu.com%3Fname%3D%E5%B0%8F%E6%98%8E%26age%3D20

     */

}

/// 服務端會對請求進行UTF-8解碼一次苫费,請確保請求中的字符只進行一次UTF-8編碼谅河。


URL中含有中文并且拼接額外參數(shù)

NSString *originUrlString = @"https://www.baidu.com?name=小明&age=20";





//需要拼接的參數(shù):轉(zhuǎn)為通過&拼接

NSMutableDictionary *urlParamsDic = [NSMutableDictionary dictionary];

[urlParamsDic setValue:@"22" forKey:@"sex"];

[urlParamsDic setValue:@"one" forKey:@"class"];

__block NSMutableString *joinStr = [NSMutableString string];

if (urlParamsDic && [urlParamsDic isKindOfClass:[NSDictionary class]] && urlParamsDic.count) {

    

    [urlParamsDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {

        if (key && obj) {

            [joinStr appendFormat:@"%@=%@&",key,obj];

        }

    }];

    if ([joinStr hasSuffix:@"&"]) {

        [joinStr deleteCharactersInRange:NSMakeRange(joinStr.length-1, 1)];

    }

}

///joinStr = sex=22&class=one



/**

 *url中含有中文,先對其encode生成NSURL

 * 拼接后再decode,最后再對拼接后的encode

 */

//1.encode生成NSURL

NSURL *originUrl = [NSURL URLWithString:[originUrlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];

///originUrl = https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20

//2.在url后拼接參數(shù)

NSString *latestURLString = @"";

BOOL cointainQuery = NO;

if (joinStr.length == 0 || [originUrl.query rangeOfString:joinStr].location != NSNotFound) {

    //其中,若joinStr = 0則表示默認包含該空字符串

    cointainQuery = YES;///

}



if (cointainQuery) {

    latestURLString = originUrl.absoluteString;

}else{

    ///originUrl.query: name=%E5%B0%8F%E6%98%8E&age=20

    if (originUrl.query.length>0) {

        latestURLString = [NSString stringWithFormat:@"%@&%@", originUrl.absoluteString,joinStr];

        ///https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20&sex=22&class=one

    }else{

        BOOL hasSuffix = [originUrl.absoluteString hasSuffix:@"?"];

        latestURLString = [NSString stringWithFormat:@"%@%@%@",originUrl.absoluteString, hasSuffix ? @"":@"?", joinStr];

    }

}

///

//3.拼接后decode

latestURLString = [latestURLString stringByRemovingPercentEncoding];

///latestURLString = https://www.baidu.com?name=小明&age=20&sex=22&class=one

///

//4.最后對對接后的encode

latestURLString =  [latestURLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

///latestURLString =https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20&sex=22&class=one

NSLog(@"%@",latestURLString);


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市匹层,隨后出現(xiàn)的幾起案子魂那,更是在濱河造成了極大的恐慌蛾号,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涯雅,死亡現(xiàn)場離奇詭異鲜结,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門精刷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拗胜,“玉大人,你說我怎么就攤上這事怒允」∪恚” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵纫事,是天一觀的道長勘畔。 經(jīng)常有香客問我,道長丽惶,這世上最難降的妖魔是什么炫七? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮蚊夫,結(jié)果婚禮上诉字,老公的妹妹穿的比我還像新娘。我一直安慰自己知纷,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布陵霉。 她就那樣靜靜地躺著琅轧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪踊挠。 梳的紋絲不亂的頭發(fā)上乍桂,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音效床,去河邊找鬼睹酌。 笑死,一個胖子當著我的面吹牛剩檀,可吹牛的內(nèi)容都是我干的憋沿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼沪猴,長吁一口氣:“原來是場噩夢啊……” “哼辐啄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起运嗜,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤壶辜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后担租,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砸民,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了岭参。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片便贵。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖冗荸,靈堂內(nèi)的尸體忽然破棺而出承璃,到底是詐尸還是另有隱情,我是刑警寧澤蚌本,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布盔粹,位于F島的核電站,受9級特大地震影響程癌,放射性物質(zhì)發(fā)生泄漏舷嗡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一嵌莉、第九天 我趴在偏房一處隱蔽的房頂上張望进萄。 院中可真熱鬧,春花似錦锐峭、人聲如沸中鼠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽援雇。三九已至,卻和暖如春椎扬,著一層夾襖步出監(jiān)牢的瞬間惫搏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工蚕涤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留筐赔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓揖铜,卻偏偏與公主長得像茴丰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蛮位,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容