【问题标题】:SyntaxError: Unexpected end of JSON input at parse (<anonymous>) in AJAX callSyntaxError:在 AJAX 调用中解析(<匿名>)时 JSON 输入意外结束
【发布时间】:2021-04-12 18:15:36
【问题描述】:

上下文

我刚刚将我的网站服务器升级到 VPS,并且自从将我的文件移动到新服务器后,在转换时遇到了一些问题。其中之一是,在这台服务器上,我的一个功能运行不正常。函数getRandomArticles() 从我的 mySQL 数据库中获取用户发布的文章。在我的本地服务器和我以前的共享服务器上,它运行良好。但是,当我在 VPS 上运行以下函数时,我收到错误 parserror

SyntaxError: Unexpected end of JSON input at parse (<anonymous>) at VM3130  
jquery.min.js:2 at l (VM3130 jquery.min.js:2) at XMLHttpRequest.<anonymous>  
(VM3130 jquery.min.js:2)  

(来自错误回调函数中的console.log(error)console.log(errorThrown)

这是返回错误的函数getRandomArticles()

    var ids = [];

    function getRandomArticles() {

        $.ajax({
            url: 'includes/articles/getRandomArticles.php',
            type: 'GET',
            dataType: 'json',
            success: function(data) {

                //code irrelevant to problem

            },
            error: function(requestObject, error, errorThrown) {
                console.log(error);
                console.log(errorThrown);
            }
        });
    }

这是我的 PHP 代码:

<?php

include '../dbh.inc.php';

if ($_SERVER['REQUEST_METHOD'] == 'GET') {

$q = "SELECT articles.article_id, articles.title, articles.article, articles.idUsers, users.uidUsers, articlecoverimages.image, profileimages.image AS profileImage 
      FROM articles 
      JOIN users 
      JOIN articlecoverimages 
      JOIN profileimages ON users.idUsers = articlecoverimages.idUsers AND articles.article_id = articlecoverimages.article_id AND profileimages.idUsers = users.idUsers 
      WHERE articles.published = ? AND articles.approved = 1 
      ORDER BY RAND()
      LIMIT 5";
$stmt = mysqli_prepare($conn, $q);
mysqli_stmt_bind_param($stmt, 's', $published);

$published = "yes";

mysqli_stmt_execute($stmt);

$r = mysqli_stmt_get_result($stmt);

if ($r) {

    if (mysqli_num_rows($r) == 0) {
    
        $data['error'] = "";
        $results[] = $data;

    } else {

        while ($row = mysqli_fetch_array($r)) {
            
            $data['articleId'] = $row['article_id'];
            $data['title'] = $row['title'];
            $data['article'] = strip_tags(htmlspecialchars_decode($row['article'], ENT_QUOTES));
            $data['idUsers'] = $row['idUsers'];
            $data['uidUsers'] = $row['uidUsers'];
            $data['image'] = $row['image'];
            $data['profileImage'] = $row['profileImage'];
            $results[] = $data;

        }       

    }

    echo json_encode($results);

}

mysqli_stmt_close($stmt);

mysqli_close($conn);

}

发生这些错误时,PHP 代码没有响应。如果没有错误,它会使用 JSON 数组进行响应。但是,当我回显特定行(例如echo $row['article'];)时,即使出现错误,该特定数据也会发送。因此,在这种情况下,只会返回文章的名称。

当我多次刷新页面时,代码终于可以正常工作并加载文章数据。然而,这只在大约 30-40% 的时间里有效,似乎是随机的。

我尝试过的事情

我使用echo json_encode($results) 来返回 AJAX 调用指向的 PHP 文件的值,所以我在这里使用 JSON。当我只是说echo $results[] 时,有一个错误,当我从 AJAX 参数中删除 dataType: json 时,也有一个错误(以防它们具有解决问题的任何合法潜力)。

问题

知道这个函数有什么问题吗?

更新

我发现当我删除线时

$data['article'] = strip_tags(htmlspecialchars_decode($row['article'], ENT_QUOTES));

所有其他行在 PHP 文件中返回。当我删除除上一行之外的所有其他行时,错误仍在继续。每次。所以,删除

$data['article'] = strip_tags(htmlspecialchars_decode($row['article'], ENT_QUOTES));

修复了这个问题,除了我需要能够返回这一行,它给出了文章内容本身。我对获取文章内容的其他三个文件也有同样的问题,所有这些文件都有相同的行(并且所有这些文件都通过删除该行来修复)。不过,这很奇怪,因为其他指定文章主题的文件能够很好地获取文章内容。我已经尝试在我的 VPS 上重置所有内容;数据库,apache服务器,我能做的一切,都无济于事。根据这一发现,似乎 PHP 文件是这里的问题,但似乎没有解决问题的潜在解决方案。同样,该文件在我的本地服务器上运行良好,在我以前的共享服务器上运行良好,但在这个新服务器上,它有问题。我什至删除了文件并制作了新文件,以查看文件本身是否导致任何类型的错误,这也不起作用。

另外,如前所述,虽然

$data['article'] = strip_tags(htmlspecialchars_decode($row['article'], ENT_QUOTES))

当我删除echo json_encode($results) 和存储在$results 数组中的所有其他列值并简单地回显$row['article'] 时(像这样):

while ($row = mysqli_fetch_array($r)) {

    echo strip_tags(htmlspecialchars_decode($row['article'], ENT_QUOTES));

}

文章内容返回。知道为什么会出现这个问题吗?

这是文章数据库中“文章”列的结构:

article TEXT NOT NULL

【问题讨论】:

  • 收到错误时的响应是什么?
  • @Nick 发生错误时没有响应。但是,当我从数据库中回显特定行时,例如 echo $row['article'],尽管出现错误,仍会返回文章。如果这没有意义,请告诉我。
  • 如果在if 测试之前初始化$results = array('test'); 会发生什么,您仍然没有得到响应吗?
  • @Nick 是的,如果我这样做,我仍然没有得到任何回应。
  • 抱歉,意思是说在if 语句之后也需要echo json_encode($results);

标签: php jquery mysql sql ajax


【解决方案1】:

在回显之前最好的做法是使用header('Content-Type: application/json'); 将响应的标头设置为json(通常我将标头设置在php 脚本的开头)。有时浏览器可能会将回复视为 html,而不是 JSON,这可能是其工作不一致的原因之一。

现在您应该能够在不剥离标签的情况下设置文章,因为您明确告诉浏览器这是 json,而不是 html,因此将此行更改为 $data['article'] = $row['article'],让json_encode 处理转义字符。

如果仍然无法正常工作,您能否发布在浏览器检查器的网络选项卡中看到的 API 答案?

编辑: 显然它不起作用,因为数据库中的字符串中有一些无效字符。这些通常是在从使用这些字符进行格式化的其他软件(如 ms word)复制文本时引入的,并且很难摆脱所有这些字符。 我建议你去阅读this answer,你应该在添加新文章之前应用这个技术。而且由于您已经有损坏的文章,因此您必须在阅读数据库中的文章后应用它

可能适用于您的情况的快速而肮脏的解决方案:

$text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');

【讨论】:

  • 感谢您的回复。在打开&lt;?php 标签后添加header('Content-Type: application/json'); 并删除剥离功能后,我仍然遇到同样的问题;该代码大约有 30% 的时间有效,似乎是随机的。当代码不起作用时,网络中的 PHP 文件没有响应,现在响应以粗体字符显示“Nothing to preview”。
  • 奇怪的是,它有 30% 的时间都在工作,这可能是您的 VPS 提供商的问题?您可以尝试在设置标头后立即编辑您的 php 文件以返回一个虚拟 json 以查看它是否始终有效吗?
  • 我建议从您的问题中删除所有不相关的细节并将其归结为minimal reproducible example。通过这种方式,志愿者可以专注于您问题的单一方面。我们需要调试细节,而不是模糊的 / 30% 的结果。
  • @brein 我就是这么想的——我现在想不出任何其他原因。为了回答你的问题,如果这足够了,当我编辑出$data['article'] = $row['article'] 行时,PHP 文件每次都会返回所有其他值(文章 ID、标题、日期等),这就是我认为该行的原因以某种方式导致了问题。
  • 也许文章单元格中有一些奇怪的字符阻止 json_encode 生成有效的 json。有些文章没有那个字符,这就是为什么有时它会起作用。所以可能php正在抛出通知或错误,但它们被静音了,因为我假设这个服务器被配置为生产,所以它隐藏了通知/警告/错误。你应该在你的服务器上检查 php 记录它遇到的所有错误的文件,你可能会发现一些有用的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2019-09-07
  • 2021-06-04
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
相关资源
最近更新 更多