0x00 背景
在如以往一樣寫(xiě)著代碼, 發(fā)現(xiàn)了問(wèn)題, 舉個(gè)例子 let url = URL(string: "https://www.baidu.com?search=你好")
, 按照 iOS17 之前沒(méi)有編碼的字符串是生成不了 url 的, 這里的 url == nil
但是在 iOS17 遇到的問(wèn)題是不一樣了, 猶豫服務(wù)器數(shù)據(jù)沒(méi)有注意這個(gè), 客戶端也沒(méi)有寫(xiě)編碼, 在 iOS17 Xcode15 寫(xiě)的時(shí)候并沒(méi)有任何異樣, 在測(cè)試手里的設(shè)備就出問(wèn)題了
0x01 問(wèn)題在哪
查閱了官網(wǎng)文檔 https://developer.apple.com/documentation/foundation/url/3126806-init, 發(fā)現(xiàn)有個(gè)重要的提示
Important
For apps linked on or after iOS 17 and aligned OS versions,URL
parsing has updated from the obsolete RFC 1738/1808 parsing to the same RFC 3986 parsing asURLComponents
. This unifies the parsing behaviors of theURL
andURLComponents
APIs. Now,URL
automatically percent- and IDNA-encodes invalid characters to help create a valid URL.
根據(jù)這段提示知道了, 在 iOS 17 之前,URL 初始化時(shí)支持的是較久的 RFC 1738/1808
標(biāo)準(zhǔn), iOS17 后全面支持 RFC 3986
標(biāo)準(zhǔn)
0x02 RFC 是什么
RFC 是 Request for Comments
的首字母縮寫(xiě),是互聯(lián)網(wǎng)工程任務(wù)組 (IETF)的對(duì)于 URL 的規(guī)范出的文檔,其中包含有關(guān)互聯(lián)網(wǎng)和計(jì)算機(jī)網(wǎng)絡(luò)相關(guān)主題(如路由、尋址和傳輸技術(shù))的規(guī)范和組織說(shuō)明胸囱。
0x03 怎么兼容
iOS 17 有一個(gè) api public init?(string: String, encodingInvalidCharacters: Bool)
, 其中 encodingInvalidCharacters
,這個(gè)參數(shù)代表是否 encoding 掉無(wú)效的字符,如果傳 false混滔,URL 的行為將會(huì)和 iOS 16 上一致。
// iOS 16
let url = URL(string: "https://www.baidu.com?search=你好") // => nil
// iOS 17
let url = URL(string: "https://www.baidu.com?search=你好", encodingInvalidCharacters: false) // => nil