Swift URL encode


前言

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

在1994年訂制的RFC1738文檔中,對字符串中的除了- _ .之外的所有非字母數字字符都替換成百分號(%)后跟兩位十六進制數,十六進制數中字母必須為大寫。

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

Swift url encode

addingPercentEncoding(withAllowedCharacters:是iOS7之后出現的新API用於url encode

標准轉碼

所有類型的URL中,"-_.~"都不應該被轉碼

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包含的是所有不需要被轉碼的字符,可以用兩句代碼驗證:

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

所以,自定義轉碼字符的集合應該取反字符集:

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

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

Objective-C url encode

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

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));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM