我有一个简单的 GET 登录请求。用户名为银色,密码为 MOto& @ 10
我正在使用SwiftHttp框架来处理请求。在点击登录请求时,我总是得到错误的回复
然而,当在浏览器上点击登录请求URL(用服务器替换实际域)时,我得到了真实:
https://server/api/check-access/by-login-pass?_key=wlyOF7TM8Y3tn19KUdlq&login=silver&pass=MOto%26@10
密码中的& 编码有问题。虽然我用百分比编码取而代之。这是我的代码:
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
}
}
答案 0 :(得分:5)
一种合适的方法是使用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%26@10"
PS:我完全赞同luk2302的评论。
答案 1 :(得分:0)
我决定为我的GET请求完全定制,因为其他一切都不想工作并让我生气。我使用了不同的请求,比如从我们的服务器获取列表。登录是通过POST请求完成的,这更容易。
但是,坚持GET请求: 我需要像&#34; +&#34;和&#34; /&#34;编码... 首先,我无法得到&#34; +&#34;用&#34; stringByAddingPercentEncodingWithAllowedCharacters编码&#34;方法。 所以我为String建立了自己的扩展:
extension String
{
return CFURLCreateStringByAddingPercentEscapes(
nil,
self as CFString,
nil,
"!*'();:@&=+$,/?%#[]" as CFString,
CFStringBuiltInEncodings.UTF8.rawValue
) as String
}
第二步是将此添加到我的网址以获取最终请求。我想使用URLQueryItems并使用url.query或url.queryItems将它们添加到url。不好意外:我已经正确编码的字符串再次被编码,每个&#34;%&#34;在它里面成了&#34;%25&#34;使它无效。 -.-
所以现在我将每个编码值附加到一个字符串,该字符串将被添加到url中。感觉不是很敏捷&#34;但好吧..
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)!
希望这可以帮助某人并节省几个小时:/