【问题标题】:Values in nested in JSON response not being parsed嵌套在 JSON 响应中的值未被解析
【发布时间】:2019-06-27 21:24:27
【问题描述】:

我正在对端点进行 REST 调用,但遇到了一个问题,即内部属性保持字符串而不转换为 Javascript。

这是我得到的:

"43750": {
    "taskId": 43750,
    "statusId": 1,
    "set_at": "2019-03-27 16:20:51",
    "userId": 2,
    "value": "[{\"text\":\"Recreational Vehicle\"}]" <-- Problem
},

这是我应该得到的(旧 API 响应):

"43750": {
  "userId": "2",
  "timestamp": "2019-03-27 16:20:51",
  "value": [
      {
         "text": "Recreational Vehicle"
      }
   ],
   "statusId": "1"
},

这些是来自 Chrome 的 DevTools 网络部分的响应选项卡中的 sn-ps。

由于某种原因,对象数组没有被解析为 javascript,而是剩余的字符串。我在 PHP 中将 Content Type 设置为 json 并在请求中使用了 json 数据类型。我错过了什么?

前端

  $.ajax({
        type: 'POST',
        dataType: 'json',
        url: API_URL,
        data: {
           action: 'getProject',
           projectId: this.getActiveProjectId()
        },
        success: function (response) {

            console.log('[AJAX RESPONSE] LOAD ACTIVE PROJECT', response);
            debugger;
        }
    });

后台

<?php
$default_options = [
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        ];

$pdo = new PDO(
    sprintf(
    "dblib:host=%s;dbname=%s",
        $server,
        $database
    ),
    $user,
    $pass,
    $default_options
 );

/* Determine action, handle request */

/* Do PDO Query */    
$tasks = $statement->fetchAll();

header("Access-Control-Allow-Origin: *");
header('Content-Type: application/json');

echo json_encode($tasks, JSON_PRETTY_PRINT);

编辑:

关于旧 API 的详细信息:

前端是一样的。后端由 MariaDB、PHP 和 mysqli_* 命令组成。我现在正在将其转换为使用 SQL Server 2008 和 PDO。

所以最后一个 API 就是这样做的:

$SQL = 'SELECT * FROM Project WHERE projectId='.$projectId;
$project = mysqli_fetch_assoc(mysqli_query($db, $SQL));
while ($taskRow = mysqli_fetch_assoc($result)) {
        $project['tasks'][$taskRow['taskId']] = [
            'userId' => $taskRow['userId'],
            'timestamp' => $taskRow['timestamp'],
            'value' => json_decode($taskRow['dataValue']),
            'statusId' => $taskRow['statusId']
        ];
}

$SQL = 'SELECT * FROM Task WHERE projectId='.$projectId.' ORDER BY timestamp ASC';
$result = mysqli_query($db, $SQL);
while ($commentRow = mysqli_fetch_assoc($result)) {
        $project['tasks'][$commentRow['taskId']]['comments'][] = [
            'text' => $commentRow['commentText'],
            'timestamp' => $commentRow['timestamp'],
            'userId' => $commentRow['userId']
        ];
}

header("Access-Control-Allow-Origin: *");

json_encode([
        'success' => true,
        'project' => $project
    ], JSON_PRETTY_PRINT);

【问题讨论】:

  • 因为你是 json_encode-ing 整个对象 - 它会将那些不能立即识别为数字的东西视为字符串。
  • @JackBashford 这似乎不是旧 API 的问题。它有一个带有任务数组属性的项目对象,并且仍在正确解析它们。有什么可以正确强制我丢失的吗?
  • 您似乎在 value 列中存储了一个 JSON 字符串。当您从数据库中提取它时,它只是一个简单的字符串,这就是它在json_encode() 中的处理方式
  • 另外,您一直在引用“旧 API”。实际看到可能会有所帮助,因此我们可以发现差异。
  • 使用 SQL Server 2008 可能会丢失一个功能?

标签: javascript php json rest


【解决方案1】:

表中的value 列包含JSON 字符串。您需要在发送响应之前对其进行解码:

foreach ($tasks as &$task) {
    $task['value'] = json_decode($task['value']);
}

或在 JavaScript 中执行:

success: function(response) {
    response.forEach(r => r.value = JSON.parse(r.value));
    // rest of success function
}

【讨论】:

  • 此步骤之前不是必需的(在 MariaDB 上使用 PHP/mysqli_*)。切换到 SQL Server 2008 是否会丢失此功能?
  • 您在 MariaDB 中使用的是 JSON 数据类型吗? SQL-Server 2008 可能没有该数据类型,因此您现在将其存储为 VARCHAR。听起来 JSON 数据类型是自动解码的,但 VARCHAR 不会发生这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 2018-07-15
  • 2016-09-03
  • 2023-03-20
  • 2019-02-26
  • 2014-01-10
相关资源
最近更新 更多