Swift URLSession 的行为不像 Curl 或 HTTParty
Swift URLSession doesn't behave like Curl or HTTParty
背景
我正在开发一个 swift 项目,其中 particle.io
设置了两条腿的身份验证部分。基本上这是一个 POST 请求。
我的问题是我可以通过 CURL
和 HTTParty. (Like below) but with
URLSession` 获得正确的响应,响应是 404。
通过 CURL
curl -X POST -u "abcd:secret" -d password=true -d email="wwsd@gmail.com" https://api.particle.io/v1/orgs/xxx/customers
来自 HTTPParty
require 'HTTParty'
def register_spark_two_legged_user(query)
return HTTParty.post("https://api.particle.io/v1/orgs/xxx/customers", body: query, basic_auth:{"username":"abcd","password":"secret"})
end
query = {"email":"wwsd@gmail.com", "no_password":true}
json = register_spark_two_legged_user query
p json
我想在 Swift:
func twoLegged() {
let urlString = "https://api.particle.io/v1/orgs/xxx/customers"
let parameters = ["email":"wwsd@gmail.com","no_password":true] as [String : Any]
let userName = "abcd"
let password = "secret"
let loginString = userName+":"+password
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
let url = URL(string: urlString)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
URLSession.shared.dataTask(with: url) { (data: Data?, response: URLResponse?, error: Error?) in
if let e = error {
print(e.localizedDescription)
} else {
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
debugPrint(response as Any)
print(json)
}
}.resume()
我错过了什么吗?谢谢您的帮助。这里有一个 link 可能有用:community.particle.io
编辑 我改了 httpBody 还是不行。
var comp = URLComponents()
comp.queryItems = [
URLQueryItem(name: "no_password", value: "true"),
URLQueryItem(name: "email", value: "wwsd@gmail.com"),
]
request.httpBody = comp.query?.data(using: String.Encoding.utf8)
request.setValue("application/x-www-form-urlencode", forHTTPHeaderField: "Content-Type")
输出为
Optional({
error = "Not Found";
ok = 0;
})
在 curl
中,您将数据作为 application/x-www-form-urlencoded
发送出去,即以
的形式
no_password=true&email=wwsd@gmail.com
但在 Swift 中,您发送的数据为 JSON。
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
# wrong: form data is expected, not JSON.
您可以使用 URLComponents
和 URLQueryItem
格式化为 application/x-www-form-urlencoded
:
var comp = URLComponents()
comp.queryItems = [
URLQueryItem(name: "no_password", value: "true"),
URLQueryItem(name: "email", value: "wwsd@gmail.com"),
]
request.httpBody = comp.query?.data(using: .utf8)
此外你没有将请求传递到 URLSession...
URLSession.shared.dataTask(with: request) { ... }
// ^~~~~~~ you were passing `url`.
背景
我正在开发一个 swift 项目,其中 particle.io
设置了两条腿的身份验证部分。基本上这是一个 POST 请求。
我的问题是我可以通过 CURL
和 HTTParty. (Like below) but with
URLSession` 获得正确的响应,响应是 404。
通过 CURL
curl -X POST -u "abcd:secret" -d password=true -d email="wwsd@gmail.com" https://api.particle.io/v1/orgs/xxx/customers
来自 HTTPParty
require 'HTTParty'
def register_spark_two_legged_user(query)
return HTTParty.post("https://api.particle.io/v1/orgs/xxx/customers", body: query, basic_auth:{"username":"abcd","password":"secret"})
end
query = {"email":"wwsd@gmail.com", "no_password":true}
json = register_spark_two_legged_user query
p json
我想在 Swift:
func twoLegged() {
let urlString = "https://api.particle.io/v1/orgs/xxx/customers"
let parameters = ["email":"wwsd@gmail.com","no_password":true] as [String : Any]
let userName = "abcd"
let password = "secret"
let loginString = userName+":"+password
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
let url = URL(string: urlString)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
URLSession.shared.dataTask(with: url) { (data: Data?, response: URLResponse?, error: Error?) in
if let e = error {
print(e.localizedDescription)
} else {
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
debugPrint(response as Any)
print(json)
}
}.resume()
我错过了什么吗?谢谢您的帮助。这里有一个 link 可能有用:community.particle.io
编辑 我改了 httpBody 还是不行。
var comp = URLComponents()
comp.queryItems = [
URLQueryItem(name: "no_password", value: "true"),
URLQueryItem(name: "email", value: "wwsd@gmail.com"),
]
request.httpBody = comp.query?.data(using: String.Encoding.utf8)
request.setValue("application/x-www-form-urlencode", forHTTPHeaderField: "Content-Type")
输出为
Optional({
error = "Not Found";
ok = 0;
})
在 curl
中,您将数据作为 application/x-www-form-urlencoded
发送出去,即以
no_password=true&email=wwsd@gmail.com
但在 Swift 中,您发送的数据为 JSON。
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
# wrong: form data is expected, not JSON.
您可以使用 URLComponents
和 URLQueryItem
格式化为 application/x-www-form-urlencoded
:
var comp = URLComponents()
comp.queryItems = [
URLQueryItem(name: "no_password", value: "true"),
URLQueryItem(name: "email", value: "wwsd@gmail.com"),
]
request.httpBody = comp.query?.data(using: .utf8)
此外你没有将请求传递到 URLSession...
URLSession.shared.dataTask(with: request) { ... }
// ^~~~~~~ you were passing `url`.