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

Posted

技术标签:

【中文标题】PHP REST 服务中的 JSON 格式问题从 AFNetworking 2.0 接收 POST【英文标题】:JSON format issue in PHP REST service receiving POST from AFNetworking 2.0 【发布时间】:2015-03-20 18:21:02 【问题描述】:

我有一种情况,我使用 AFNetworking 2.0 代码从我的 ios 代码中发布一个 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 字符串?

【问题讨论】:

做一件事,var_dump($POST);exit;脚本的第一行,看看输出是什么或 echo 'POST Params'; var_dump($POST);回声'获取参数'; var_dump($GET);退出; @FawadMasud 不,这不是x-www-form-urlencoded 请求。所以你不要使用$_POST$_GET 对于 [AFHTTPResponseSerializer 序列化器],如果我在我的服务器代码中编写: $json_str = json_encode($return_str);回声 $json_str;我收到错误:“不可接受的内容类型:文本/html。 【参考方案1】:

几个问题

    您的AFHTTPSessionManager 使用默认的AFJSONResponseSerializer,但只是覆盖acceptableContentTypes。只有当您的服务器代码确实返回 JSON 并且未能在 Content-Type 标头中指定时,您才会这样做。

    如果服务器真的没有返回 JSON,而不是更改 acceptableContentTypes,你应该简单地使用 AFHTTPSessionManager

    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    

    或者让服务器返回 JSON 并确保它指定了正确的 Content-Type 标头:

    <?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

    构建parameters 的演示机制不正确。您正在创建一个 JSON 字典,其中只有一项,它本身就是 JSON 的字符串表示形式。

    我建议您不要将字符串表示形式放入字典中,而是将实际字典放入字典中。所以,如果你真的有一个 NSData 的 JSON,将它转换回嵌套的 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 会有点愚蠢,只是转身将其提取出来,而是您只需在@987654341 中使用原来的NSDictionary @,但希望这能说明这一点。

因此,将所有这些放在一起,假设您更改服务器代码以返回格式正确的 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 并返回到客户端应用程序,它将使用默认的 AFJSONResponseSerializer解析它并记录它。

【讨论】:

感谢@Rob 提供详细信息。我做了所有这些,现在得到:error=Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x19f92370 com.alamofire.serialization.response .error.response= URL: blah.com/service.php 状态码: 200, headers Connection = "keep-alive"; “内容长度”= 26; “内容类型”=“文本/html”;日期 =“格林威治标准时间 2015 年 3 月 20 日星期五 22:37:51”;服务器 = "Apache/2.4.6 (Ubuntu)"; "X-Powered-By" = "PHP/5.5.3-1ubuntu2.6"; , 如果我这样做: $json);回声 json_encode($array_str);我得到一个 JSON 字符串: project = project = .... 有什么想法吗? 另外,如果我写 $array_str = array($json); 我只会得到 project = .... 而不是两个“项目”。我怎样才能过滤掉“项目”,只得到身体的其余部分?我没有设置:manager.responseSerializer = [AFHTTPResponseSerializer serializer] ... 似乎正在返回 JSON 字符串,前面有“项目”。 是的,你不需要AFHTTPResponseSerializer 的东西(也不需要acceptableContentTypes 的东西)。只有当您的响应不是 JSON(或者是忽略正确设置其标头的 JSON)时,您才需要这样做。 感谢@Rob 的帮助。我的意图不仅仅是来回穿梭。当我将 JSON 帖子加载到服务器上的数组中并发送带有键“项目”的字典时,我似乎没有处理该数组。但如果我只是发送一个 JSON 字符串,该数组似乎工作正常。是因为前面的“项目”导致问题吗?如何在服务器上记录收到的 JSON。我做了file_put_contents(filename),但没有看到任何数据。

以上是关于PHP REST 服务中的 JSON 格式问题从 AFNetworking 2.0 接收 POST的主要内容,如果未能解决你的问题,请参考以下文章

无法从服务器上的 PHP 文件中获取 JSON 格式的数据

从 WCF REST Web 服务返回包装在回调函数中的 JSON

如何在C#中解析/反序列化从rest服务返回的JSON

无法从 Spring Boot REST 中的 Hibernate POJO 返回 JSON

PayPal REST API 格式错误的 JSON 错误

C# Rest 服务 - 无法在服务方法中接收 JSON 请求