iOS NSURL 編碼, 不同字段解析結果不同引發的 bug

文章地址
在 RFC 3986 文檔中規定,URL 中只允許包含以下四種:

  1. 英文字母 a-z 以及 A-Z
  2. 數字 0-9
  3. 4個特殊字符:中橫線 -、下劃線 _、小數點 . 以及波浪線 ~
  4. 保留字符:!*'();:@&=+$,/?#[]

除上述四種字符外,所有其他字符都將被替換成百分號 % + 兩位十六進制數。

@":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`\r\n\t" // @"" 是 OC 語法, 關注引號中字符即可

這33個字符需要轉義, 其中

@" \"#%&()+,/:;<>=?@\\|"

是特殊字符轉義編碼, 一定要轉義

@"{}^[]`~" 

這些屬于不安全字段, 傳輸過程中某些網關會篡改這些字符, 最好也轉義
對于 NSURLComponents 不能解析的字符串有

@"[] \"<>%{}|\\^`\r\n\t"

這 16 個字符, 執行 urlComponents.queryItems 為 nil

特殊字符的編碼如下:

ASCII 字符 URL-編碼
空格 %20
! %21
" %22
# %23
$ %24
% %25
& %26
' %27
( %28
) %29
* %2A
+ %2B
, %2C
- %2D
. %2E
/ %2F
: %3A
; %3B
< %3C
= %3D
> %3E
? %3F
@ %40
[ %5B
\ %5C
] %5D
^ %5E
_ %5F
` %60
{ %7B
| %7C
} %7D
~ %7E

問題原由

在 url 解析參數時, 對 query 參數做了 [NSString stringByRemovingPercentEncoding] 轉義, 替換掉了所有的 %20 轉義字符, 然后將轉移后的 url 交給 WebView 展示. 然后 webview 在使用 NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url]; 解析 url 時, 發現 url 含有'^|'等字符就直接解析失敗, 造成 bug, 解決辦法也很簡單, 在解析失敗的時候, 針對

[] \"<>%{}|\\^`\r\n\t

這些字符做重新編碼, 然后再使用 NSURLComponents 解析即可, 代碼如下

NSString *specialString = @"[] \"<>%{}|\\^`\r\n\t";
NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:specialString] invertedSet];
NSString *encoded = [url stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
// 再解析 encoded 即可

參考文檔

關于URL編碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容