SyntaxError: "JSON.parse: неожиданное непробельное..." при возврате JSON из PHP

Я столкнулся с проблемой, когда JSON, возвращенный из PHP-запроса, недействителен, и я не совсем понимаю, почему; Я все еще учусь. Когда datatype исключен, возвращается следующий код:

{"Customer_ID":"0", "FirstName":"John", "LastName":"Smith"}
{"Customer_ID":"1", "FirstName":"Jane", "LastName":"Smith"}

в противном случае он возвращает:

SyntaxError: "JSON.parse: unexpected non-whitespace character after ..."

Я подумал, что это может быть связано с тем, что запись не возвращается в одном ответе JSON, но я не вижу в этом проблемы, поскольку параллельные ответы - это JSON. Любые идеи? Любые предложения? Не стесняйтесь указывать на семантические проблемы.

HTML:

getRecord("*", "customer", "");

JavaScript:

function getRecord(field, table, condition) {
    var request = $.ajax({
        url: "./handler.php",
        method: "GET",
        dataType: "JSON",
        cache: "false",
        data: {
            action: "SELECT",
            field: `${field}`,
            table: `${table}`,
            condition: `${condition}`,
        },
    });

    request.done(function(data, status, xhr) {
        console.info(data, status, xhr);
    });

    request.fail(function(xhr, status, error) {
        console.info(xhr, status, error);
    });

};

PHP:

<?php

    # IMPORT SETTINGS.
    include "settings.php";

    # FUNCTION DISPATCHER.
    switch($_REQUEST["action"]) {

        case "SELECT":
            getRecord($conn);
            break;

        default:
            printf('Connection Error: Access Denied.');
            mysqli_close($conn);
    }

    # LIST OF COLUMNS THAT WE NEED.

    function getRecord($conn) {
        $table = $_REQUEST["table"];
        $field = $_REQUEST["field"];
        $condition = $_REQUEST["condition"];

        if (!empty($condition)) {
            $query = "SELECT $field FROM $table WHERE $condition";
        } else {
            $query = "SELECT $field FROM $table";
        }

        if ($result = mysqli_query($conn, $query)) {
            while ($record = mysqli_fetch_assoc($result)) {
                echo json_encode($record);
            }
        }

        # CLOSE THE CONNECTION.
        mysqli_close($conn);

    }

?>

Обратите внимание, что такое утверждение, как $query = "SELECT $field FROM $table WHERE $condition";, вообще небезопасно. С ним хакеры смогут выполнить любую команду SQL. Вам нужно проверить каждый параметр (т. е. действительно ли $table имя таблицы?) См. SQL-инъекция.

Alexis Wilke 18.02.2019 00:17

@AlexisWilke это было то, что я начал понимать, я просто хотел обойти эту ошибку, чтобы понять, что я делаю неправильно. Я надеюсь, что все будет как можно более динамичным, но я не уверен, как именно. Одна из идей заключалась в том, чтобы составить белый список таблиц, но я не уверен, что это возможно. Любые предложения, чтобы сохранить код динамическим?

artomason 18.02.2019 00:23

Да, список ваших столов и проверка того, является ли $table одним из этих имен, будут работать. Проблема для $field заключается в том, что вам придется вводить все имена всех полей из всех ваших таблиц (вы также можете сделать SELECT против MySQL, чтобы получить информацию, но тогда вам придется тратить время каждый раз, когда вы хотите получить доступ базу данных!) Со своей стороны, я часто использую * для поля, потому что однократная загрузка всего будет намного быстрее, чем загрузка одного поля за раз. Теперь у вас есть другая проблема: вы, вероятно, не хотите возвращать пароль пользователя... (даже зашифрованный).

Alexis Wilke 18.02.2019 00:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
159
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш JSON недействителен, поскольку состоит из нескольких объектов. Что вам нужно сделать, так это поместить все ваши результаты в массив, а затем повторить json_encode этого. Попробуйте что-то вроде этого:

    $records = array();
    if ($result = mysqli_query($conn, $query)) {
        while ($records[] = mysqli_fetch_assoc($result)) {
        }
    }
    echo json_encode($records);

Это даст вам вывод, который выглядит примерно так:

[
    {"Customer_ID":"0", "FirstName":"John", "LastName":"Smith"},
    {"Customer_ID":"1", "FirstName":"Jane", "LastName":"Smith"}
]

и вы можете получить доступ к каждому из элементов в вашем Javascript с помощью чего-то вроде

let customer = data[0].FirstName + ' ' + data[0].LastName;

Я планировал использовать $.each() для возвращаемых данных, но ваш ответ решил проблему; Спасибо. Теперь мне нужно выяснить, как сохранить динамику и при этом предотвратить уязвимости.

artomason 18.02.2019 00:25

@artomason да, $.each() отлично сработает с этими данными. У Этот вопрос есть хорошая дискуссия о том, как предотвратить внедрение SQL.

Nick 18.02.2019 00:33

Другие вопросы по теме