2017-04-01 33 views
2

我有一個簡單的GET請求登錄。用戶名是和密碼是MOTO & @ 10
我使用的處理請求SwiftHttp框架。點擊登錄請求時,我總是得到回覆爲false。
然而在打在瀏覽器的登錄請求URL(替代實際域與服務器)我得到真正:
https://server/api/check-access/by-login-pass?_key=wlyOF7TM8Y3tn19KUdlq&login=silver&pass=MOto%[email protected]Swift編碼&GET參數

有一些錯誤的密碼編碼&。儘管我用百分比編碼替換了它。這裏是我的代碼:

do {    
    let passwordString = self.convertSpecialCharacters(string: password.text!) 
    print("%@", passwordString) 
    let opt = try HTTP.GET(Constants.kLoginUrl, parameters: ["login": username.text!, "pass": passwordString]) 
    opt.start { response in 
      if let err = response.error { 
       print("error: \(err.localizedDescription)") 
       return 
      } 

      print("opt finished: \(response.description)") 
      self.parseLoginResponse(response.data) 
} 
} catch _ as NSError { 

} 

這是convertSpecialCharacters

func convertSpecialCharacters(string: String) -> String { 
     var newString = string 

     let arrayEncode = ["&", "<", ">", "\"", "'", "-", "..."] 

     for (escaped_char) in arrayEncode { 
      newString = newString.encode(escaped_char) 
     } 

     return newString 
    } 

擴展編碼:

extension String { 
     func encode(_ chars: String) -> String 
     { 
      let forbidden = CharacterSet(charactersIn: chars) 
      return self.addingPercentEncoding(withAllowedCharacters: forbidden.inverted) ?? self 
     } 
    } 
+3

,請不要使用'GET'對於您一起發送密碼登錄的目的: http://stackoverflow.com/a/323286/2442804 – luk2302

+0

請參閱http://stackoverflow.com/questions/24551816/swift-encode-url – Sulthan

+0

據我瞭解SwiftHTTP的最新來源,它將百分比編碼正確地添加到'參數'。所以,如果你調用'convertSpecialCharacters(string:)',密碼是雙重編碼的。刪除'let passwordString = self.convertSpecialCharacters(string:password.text!)'這行並將'parameters'創建爲'[「login」:username.text !,「pass」:password.text!]'(假設兩個'!'在這裏是安全的。) – OOPer

回答

2

合適的方法是使用URLComponents處理所有百分號編碼:

var urlComponents = URLComponents(string: "https://server/api/check-access/by-login-pass")! 
let queryItems = [URLQueryItem(name:"_key", value:"wlyOF7TM8Y3tn19KUdlq"), 
        URLQueryItem(name:"login", value:"silver"), 
        URLQueryItem(name:"pass", value:"MOto&@10")] 
urlComponents.queryItems = queryItems 
let url = urlComponents.url 

print(url) // "https://server/api/check-access/by-login-pass?_key=wlyOF7TM8Y3tn19KUdlq&login=silver&pass=MOto%[email protected]" 

PS:我完全同意luk2302的評論。

+2

一個小警告,'URLQueryItem'不會正確地將'+'編碼爲百分號轉義。它把它留作'+',這有點令人驚訝。 – Sulthan

0

我決定對我的GET請求進行全面定製,因爲一切都不想工作,讓我生氣。我使用了不同的請求,例如從我們的服務器獲取列表。登錄是通過POST請求完成的,這很容易。

但是,堅持使用GET-請求: 我需要的字符,如「+」和「/」編碼...... 首先,我不能讓「+」與「stringByAddingPercentEncodingWithAllowedCharacters」方法進行編碼。 所以我建立了自己的擴展字符串:

extension String 
{ 
    return CFURLCreateStringByAddingPercentEscapes(
     nil, 
     self as CFString, 
     nil, 
     "!*'();:@&=+$,/?%#[]" as CFString, 
     CFStringBuiltInEncodings.UTF8.rawValue 
    ) as String 
} 

第二步是將它添加到我的網址爲最後的請求。我想使用URLQueryItems並通過使用url.query或url.queryItems將它們添加到URL。不好的驚喜:我已經正確編碼的字符串再次被編碼,其中的每個「%」變成了「%25」,使其無效。 -.-

所以,現在我已經將每個編碼值附加到將被添加到URL的字符串。不會覺得很「迅速」,但確定..

let someUrl = "https://example.com/bla/bla.json" 
var queryString = "" 
var index = 0 

// dicParam is of type [String: AnyObject] with all needed keys and values for the query 
for (key, value) in dicParam 
{ 
    let encodedValue = (value as! String).encodeUrl() 
    if index != 0 
    { 
     queryString.append("&\(key)=\(encodedValue)") 
    } 
    else 
    { 
     queryString.append("?\(key)=\(encodedValue)") 
    } 

    index += 1 
} 

let url = URLComponents(string: someUrl + queryString)! 

希望這可以幫助別人,並節省了幾個小時:/