JSON PHP REST 服务从 AFNetworking 2.0 接收 POST 中的格式问题

JSON format issue in PHP REST service receiving POST from AFNetworking 2.0

我有一种情况,我使用 AFNetworking 2.0 代码从我的 iOS 代码中 POST 一个 JSON 字符串。我的客户端代码如下所示:

NSURL *url = [NSURL URLWithString:BaseURLString];
NSString *jsonString = [[NSString alloc] initWithData:jsonPayloadForProject encoding:NSUTF8StringEncoding];

NSDictionary *parameters = @{@"project": jsonString};

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]       initWithBaseURL:url];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

[manager POST:@"service.php" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"%@", [responseObject description]);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"POST JSON for Project Error"
                                                        message:[error localizedDescription]
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
    [alertView show];
}];

JSON 看起来像这样:

{
  "Maps" : [
    {
      "Markers" : [
        {
          "marker_tag" : -790386438,
          "location_y" : 182,
          "location_x" : 344
        },
        {
          "marker_tag" : 451496476,
          "location_y" : 267,
          "location_x" : 150.5
        }
      ],
      "image_string" : "EC817509-DE49-4914-840E-5E407571F6AE.jpeg",
      "order_num" : 0,
      "name" : "Blah1",
      "id" : "EC817509-DE49-4914-840E-5E407571F6AE"
    },
    {
      "Markers" : [
        {
          "marker_tag" : -79601351,
          "location_y" : 377,
          "location_x" : 486.5,
          "image_id" : "Blah2",
          "map_id" : "146C1C09-5AE0-4E4C-83C8-B7EAA8F28A9A"
        }
      ],
      "image_string" : "146C1C09-5AE0-4E4C-83C8-B7EAA8F28A9A.jpeg",
      "order_num" : 0,
      "name" : "1st floor",
      "id" : "146C1C09-5AE0-4E4C-83C8-B7EAA8F28A9A"
    }
  ],
  "longitude" : "-222.222222",
  "latitude" : "33.33333"
}

当我使用

在我的 php 代码中读取服务器上的 JSON 字符串时
$json_str = file_get_contents('php://input');

当我这样做时,我得到以下字符串:

{ "project" = '{ \n \"Maps\" : [ \n { \n \"Markers\" : [ \n { \n \"marker_tag\n : = -790386438, \n ....

我的问题是,当我执行以下操作时,我什么也没得到。

$array_str = json_decode($json_str, true);

将其放入数组以解析数据的最佳方法是什么?我怎样才能取回我从客户发送的原始 JSON 字符串?

几个问题

  1. 您的 AFHTTPSessionManager 使用默认值 AFJSONResponseSerializer 但只是覆盖了 acceptableContentTypes。只有当您的服务器代码确实 returning JSON 并且未能在 Content-Type header.

    中指定时,您才会这样做
    • 如果服务器真的没有 returning JSON,而不是更改 acceptableContentTypes,你应该简单地使用 AFHTTPSessionManager

      manager.responseSerializer = [AFHTTPResponseSerializer serializer];
      
    • 或让服务器 return JSON 并确保它指定正确的 Content-Type header:

      <?php
      
      $json_str = file_get_contents('php://input');
      $json = json_decode($json_str, true);
      
      header('Content-Type: application/json');
      
      $result = array("received" => $json);
      echo json_encode($result);
      
      ?>
      

      完成后,我现在可以简单地从客户端代码中完全删除 acceptableContentTypes 行,并继续使用默认的 AFJSONResponseSerializer.

  2. 构建 parameters 的演示机制不正确。您正在创建一个 JSON 字典,其中只有一个项目,它本身是 JSON.

    的字符串表示形式

    与其将字符串表示形式放入字典中,我建议您将实际的字典放入字典中。所以,如果你真的有一个JSON的NSData,把它转换回嵌套的NSDictionary/NSArray结构:

    NSError *error;
    id jsonPayload = [NSJSONSerialization JSONObjectWithData:jsonPayloadData options:0 error:&error];
    NSAssert(jsonPayload, @"json parsing error: %@", error);
    
    NSDictionary *parameters = @{@"project": jsonPayload};
    

    现在,最有可能的是,使用 dataWithJSONObject 创建一个 NSData 会有点傻,只是转身将其提取出来,但您可以直接使用原始文件NSDictionaryparameters 内,但希望这能说明这一点。

因此,将所有这些放在一起,假设您将服务器代码更改为 return 格式正确的 JSON 响应,如上所述,客户端代码现在变为:

NSError *error;
id jsonPayload = [NSJSONSerialization JSONObjectWithData:jsonPayloadData options:0 error:&error];
NSAssert(jsonPayload, @"json parsing error: %@", error);

NSDictionary *parameters = @{@"project": jsonPayload};

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:url];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
// manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

[manager POST:@"service.php" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"%@", [responseObject description]);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"error=%@", error);
}];

如果你这样做,你将成功地将你的 JSON 请求发送到服务器,它将被解析,插入到一个新的关联数组中,转换回 JSON 和 returned 到客户端应用程序,它将使用默认 AFJSONResponseSerializer 来解析它并记录它。