轉(zhuǎn)義原因:避免引起歧義
現(xiàn)在URL會使用key=value的形式傳參,鍵值對間使用&分隔,如/s?username=abc& password=123&fff。正常來說,第一對鍵值是username=abc,第二對鍵值是password=123&fff。然而第二隊鍵值對中的value的值包含了特殊字符&,URL會根據(jù)這個字符分隔字符串,這就導(dǎo)致接收URL的服務(wù)器解析錯誤了。所以我們需要對會引起歧義的URL字符進(jìn)行轉(zhuǎn)義。
URL編碼原則:
使用安全的字符(沒有特殊用途或特殊意義的可打印字符)去表示那些不安全的字符。
那么那些是安全的字符,那些不是呢?
文檔規(guī)定URL中只允許包含英文字符(a-zA-Z)、數(shù)字(0-9)、-_.~4個特殊字符以及所有保留字符。
保留字符:
用作分隔不同組件的。我們知道URL可以劃分為不同的部分,如·協(xié)議、主機(jī)、路徑等。因此計算機(jī)保留了一些字符用作分隔的標(biāo)記,如冒號用于分隔協(xié)議和主機(jī),/用于分隔 主機(jī)和路徑,?用于分隔路徑和查詢參數(shù)等。還有一些字符(!$&'()*+,;=)用于在每個組件中起到分隔作用的,如=用于表示查詢參數(shù)中 的鍵值對,&符號用于分隔查詢多個鍵值對。當(dāng)組件中的普通數(shù)據(jù)包含這些特殊字符時,需要對其進(jìn)行編碼。
指定的保留字符:

不安全字符:
有些字符在URL中會引起解析程序的歧義。具體原因有很多:

注意:對于合法字符來說,編碼和不編碼是等價的。但是對于上面提到的,如果不經(jīng)過編碼,那么可能造成URL語義不同。因此對于URL,至于普通英文和數(shù)字、特殊字符$-_.+!*'()還有保留 字符,才能出現(xiàn)在未經(jīng)編碼的URL中。其他字符則都需要經(jīng)過編碼才能出現(xiàn)在URL中。
Url編碼(也叫百分比編碼:url encoding, or percent-encoding)
對于Url的非法字符,必須進(jìn)過編碼才能出現(xiàn)在url中,而目前采用的百分比編碼,就是將字符轉(zhuǎn)為對應(yīng)的16進(jìn)制標(biāo)量,然后每2位16進(jìn)制標(biāo)量前添加一個『%』。如a的16進(jìn)制ascii是61,那么百分比編碼后值是%61。而非ascii字符,如中文,則先使用utf8編碼后,在進(jìn)行百分號編碼。如『樂』的utf8編碼是E4B990,所以它的百分比編碼結(jié)果是%E4%B9%90。
Swift中的編碼過程
Alamofire.request("http://hanxiao.52kjg.cn/Api/index.php", method: .post, parameters: params, encoding: URLEncoding.default).responseJSON
我們常用的Alamofire,上面代碼中的encoding就是URL編碼過程。(所以我們使用Alamofire時, url或者參數(shù)中有特殊字符時,不用特殊處理,因為Alamofire已經(jīng)為你處理好了)
主動處理方式:
let myString = "樂"
//百分比編碼,參數(shù)表示特殊字符的種類
let percentEncode = myString.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
print(percentEncode)
//解碼百分比的編碼
let decoding = percentEncode?.removingPercentEncoding
print(decoding)
上面方法不能對一些保留字符處理,如『=』。真TM坑。另外一種方法:地址:https://stackoverflow.com/questions/24551816/swift-encode-url/24552028#
let myString = "=123/"
let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let escapedString = myString.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
print(escapedString)
}
結(jié)果:
%3D123%2F