使用 NSURLSession 复制 AFNetworking POST 请求
Replicate AFNetworking POST request with NSURLSession
POST 请求 AFNetworking
:
let urlString = "http://example.com/file.php"
let dictionary = ["key1": [1,2,3], "key2": [2,4,6]]
var error: NSError?
let data = NSJSONSerialization.dataWithJSONObject(dictionary, options: NSJSONWritingOptions.allZeros, error: &error)
let jsonString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let parameters = ["data" : jsonString!]
let manager = AFHTTPSessionManager()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.POST(urlString, parameters: parameters, success:
{
requestOperation, response in
let result = NSString(data: response as! NSData, encoding: NSUTF8StringEncoding)!
println(result)
},
failure:
{
requestOperation, error in
})
POST 请求 NSURLSession
:
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
let bodyData = NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions.allZeros, error: &error)!
request.HTTPBody = bodyData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("\(bodyData.length)", forHTTPHeaderField: "Content-Length")
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let result = NSString(data: data, encoding: NSUTF8StringEncoding)!
println(result)
}).resume()
我在服务器上有:
$data = json_decode($_POST["data"], true);
if (!$data) {
echo "Error: Invalid POST data";
return;
}
//do some stuff
echo "success";
在第二种情况下我得到 "Error: Invalid POST data"。我做错了什么?
这是因为 AFNetworking 示例未创建 JSON 请求,而您的 NSURLSession
示例是。 AFNetworking 示例正在创建一个 application/x-www-form-urlencoded
请求(其中值是您手动创建的 JSON 字符串)。您可以更改服务器代码以接受 JSON 请求或将请求更改为 application/x-www-form-urlencoded
请求。
如果您查看 Charles 之类的 AFNetworking 请求正文,您可以看到它生成如下内容:
data=%7B%22key1%22%3A%5B1%2C2%2C3%5D%2C%22key3%22%3A%5B%22Harold%20%26%20Maude%22%5D%2C%22key2%22%3A%5B2%2C4%2C6%5D%7D
如果您取消百分比转义与 data
关联的值,那实际上是
data={"key1":[1,2,3],"key3":["Harold & Maude"],"key2":[2,4,6]}
(注意,我添加了 key3
以表明转义百分比是转义标准保留字符,另外还有 &
和 +
。)
如果你想用 NSURLSession
自己做这个,你必须构建它然后像这样转义它:
let allowed = NSCharacterSet.alphanumericCharacterSet().mutableCopy() as! NSMutableCharacterSet
allowed.addCharactersInString("-._~")
let bodyString = "data=" + jsonString.stringByAddingPercentEncodingWithAllowedCharacters(allowed)!
坦率地说,这是一种非常奇怪的方法,将 JSON 嵌入到 application/x-www-form-urlencoded
请求中。我只是更改服务器以接受标准 JSON 请求(完全绕过 $_POST
变量):
$handle = fopen("php://input", "rb");
$raw_post_data = '';
while (!feof($handle)) {
$raw_post_data .= fread($handle, 8192);
}
fclose($handle);
$body = json_decode($raw_post_data, true);
顺便说一句,一旦服务器代码接受纯 JSON 请求,Swift 1.x 客户端代码将是:
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions.allZeros, error: &error)!
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let result = NSString(data: data, encoding: NSUTF8StringEncoding)!
println(result)
}).resume()
AFNetworking 等效项如下所示:
let urlString = "http://example.com/file.php"
let dictionary = ["key1": [1,2,3], "key2": [2,4,6]]
let manager = AFHTTPSessionManager()
manager.requestSerializer = AFJSONRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.POST(urlString, parameters: parameters, success:
{
requestOperation, response in
let result = NSString(data: response as! NSData, encoding: NSUTF8StringEncoding)!
println(result)
},
failure:
{
requestOperation, error in
})
POST 请求 AFNetworking
:
let urlString = "http://example.com/file.php"
let dictionary = ["key1": [1,2,3], "key2": [2,4,6]]
var error: NSError?
let data = NSJSONSerialization.dataWithJSONObject(dictionary, options: NSJSONWritingOptions.allZeros, error: &error)
let jsonString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let parameters = ["data" : jsonString!]
let manager = AFHTTPSessionManager()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.POST(urlString, parameters: parameters, success:
{
requestOperation, response in
let result = NSString(data: response as! NSData, encoding: NSUTF8StringEncoding)!
println(result)
},
failure:
{
requestOperation, error in
})
POST 请求 NSURLSession
:
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
let bodyData = NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions.allZeros, error: &error)!
request.HTTPBody = bodyData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("\(bodyData.length)", forHTTPHeaderField: "Content-Length")
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let result = NSString(data: data, encoding: NSUTF8StringEncoding)!
println(result)
}).resume()
我在服务器上有:
$data = json_decode($_POST["data"], true);
if (!$data) {
echo "Error: Invalid POST data";
return;
}
//do some stuff
echo "success";
在第二种情况下我得到 "Error: Invalid POST data"。我做错了什么?
这是因为 AFNetworking 示例未创建 JSON 请求,而您的 NSURLSession
示例是。 AFNetworking 示例正在创建一个 application/x-www-form-urlencoded
请求(其中值是您手动创建的 JSON 字符串)。您可以更改服务器代码以接受 JSON 请求或将请求更改为 application/x-www-form-urlencoded
请求。
如果您查看 Charles 之类的 AFNetworking 请求正文,您可以看到它生成如下内容:
data=%7B%22key1%22%3A%5B1%2C2%2C3%5D%2C%22key3%22%3A%5B%22Harold%20%26%20Maude%22%5D%2C%22key2%22%3A%5B2%2C4%2C6%5D%7D
如果您取消百分比转义与 data
关联的值,那实际上是
data={"key1":[1,2,3],"key3":["Harold & Maude"],"key2":[2,4,6]}
(注意,我添加了 key3
以表明转义百分比是转义标准保留字符,另外还有 &
和 +
。)
如果你想用 NSURLSession
自己做这个,你必须构建它然后像这样转义它:
let allowed = NSCharacterSet.alphanumericCharacterSet().mutableCopy() as! NSMutableCharacterSet
allowed.addCharactersInString("-._~")
let bodyString = "data=" + jsonString.stringByAddingPercentEncodingWithAllowedCharacters(allowed)!
坦率地说,这是一种非常奇怪的方法,将 JSON 嵌入到 application/x-www-form-urlencoded
请求中。我只是更改服务器以接受标准 JSON 请求(完全绕过 $_POST
变量):
$handle = fopen("php://input", "rb");
$raw_post_data = '';
while (!feof($handle)) {
$raw_post_data .= fread($handle, 8192);
}
fclose($handle);
$body = json_decode($raw_post_data, true);
顺便说一句,一旦服务器代码接受纯 JSON 请求,Swift 1.x 客户端代码将是:
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions.allZeros, error: &error)!
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let result = NSString(data: data, encoding: NSUTF8StringEncoding)!
println(result)
}).resume()
AFNetworking 等效项如下所示:
let urlString = "http://example.com/file.php"
let dictionary = ["key1": [1,2,3], "key2": [2,4,6]]
let manager = AFHTTPSessionManager()
manager.requestSerializer = AFJSONRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.POST(urlString, parameters: parameters, success:
{
requestOperation, response in
let result = NSString(data: response as! NSData, encoding: NSUTF8StringEncoding)!
println(result)
},
failure:
{
requestOperation, error in
})