Swift URL encode

前言

在WEB前端開發,服務器後臺開發,或者是客戶端開發中,對URL進行編碼是一件很常見的事情,可是因爲各個年代的RFC文檔中的內容一直在變化,一些年代久遠的代碼就對URL編碼和解碼的規則和如今的有一些區別。前端

在1994年訂製的RFC1738文檔中,對字符串中的除了- _ .以外的全部非字母數字字符都替換成百分號(%)後跟兩位十六進制數,十六進制數中字母必須爲大寫。objective-c

在2005年定義的RFC3986中,將針對- _.~四個字符以外的全部非字母數字字符進行百分號編碼。固然 根據URL的類型不一樣,有也一部分預留字符不須要進行編碼,例如查詢的URL中能夠包含? /字符,不須要轉義。更詳細文檔的能夠查看RFC 3986swift

Swift url encode

addingPercentEncoding(withAllowedCharacters:是iOS7以後出現的新API用於url encode服務器

標準轉碼

全部類型的URL中,"-_.~"都不該該被轉碼ui

var str = "-_.~" var encodeStr = str.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) print(encodeStr ?? "") // -_.~ 
var str = "#" var encodeStr = str.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) print(encodeStr ?? "") // %23 

CharacterSet

CharacterSet是一個結構體,CharacterSet.urlHostAllowed等預製類型包含了全部不須要被轉碼的字符,反過來講就是指明瞭須要被轉碼的字符。CharacterSet類中提供了一些經常使用的URL轉碼的類型:編碼

* CharacterSet.urlHostAllowed: 被轉義的字符有  "#%/<>?@\^`\{\|\}
* CharacterSet.urlPathAllowed: 被轉義的字符有  "#%;<>?[\]^`\{\|\}
* CharacterSet.urlUserAllowed: 被轉義的字符有   #%/<>?@\^`\{\|\}
* CharacterSet.urlQueryAllowed: 被轉義的字符有  "#%<>[\]^`\{\|\}
* CharacterSet.urlPasswordAllowed 被轉義的字符有 "#%/:<>?@[\]^`\{\|\}

爲何說CharacterSet.urlHostAllowed包含的是全部不須要被轉碼的字符,能夠用兩句代碼驗證:url

let unicode = "1".unicodeScalars.flatMap{ $0 }[0] print(CharacterSet.urlHostAllowed.contains(unicode)) //輸出TRUE 

因此,自定義轉碼字符的集合應該取反字符集:spa

let str2 = "#/%/<>?@" let custom = CharacterSet(charactersIn: "#").inverted let result = str2.addingPercentEncoding(withAllowedCharacters: custom) ?? "" print(result) //輸出 %23/%/<>?@ 

能夠看到只有#被編碼。在一些特殊的需求中會用到自定義編碼集合,例如BASE64轉碼後的URL編碼。code

Objective-C url encode

API調用都是同樣的,不過網上流傳的比較多的是用的C APItoken

NSString *ciphertext = @"saf#*&"; NSCharacterSet *set = [[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?%#[]"] invertedSet]; NSString *resultString = [ciphertext stringByAddingPercentEncodingWithAllowedCharacters: set]; 

C API

NSString *ciphertext = @"saf#*&"; NSString *encodedStr = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes (kCFAllocatorDefault, (CFStringRef)ciphertext, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8));
相關文章
相關標籤/搜索