You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AJAX向PHP发送JSON时重复调用出现ParseError问题求助

问题描述

单次调用test()函数时AJAX请求正常返回"ok",但同时调用两次时,一次成功一次出现JSON解析错误,错误提示为Unexpected token < in JSON at position 0。使用jQuery 2.1.4库,已尝试调整dataType、修改PHP头部等操作,问题仍未解决。

AJAX请求代码

function test(){        
    const json = {"name" : {"name" : "test", "other" : 4} };

    $.ajax({
        type: "POST",
        url: "http://localhost:8080/print.php",
        data: {m:json, mm:"5"},
        dataType: 'application/json; charset=utf-8',
        cache: false,
        success: function(neu){
            console.log(neu.status);
        },
        error: function( jqXHR, textStatus, errorThrown ) {
            console.log(textStatus);
            console.log(errorThrown);
        }
    }).fail( function( jqXHR, textStatus, errorThrown ) {
        console.log(textStatus);
        console.log(errorThrown);
    });
}

PHP代码(print.php)

<?php
  header('Access-Control-Allow-Origin: *');
  header('Content-type: application/json');
  $ticket = $_POST['m'];
  // 移除这段代码时会返回两次"ok",不知原因
  $connector = new NetworkPrintConnector("192.168.1.5",9100);
  $printer = new Printer($connector);
  //
  $response['status'] = "ok";
  echo json_encode($response);
?>

错误信息

ok
parsererror
index.php:8408 SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at n.parseJSON (jquery.js?v=270:4:5309)
at vc (jquery.js?v=270:4:7397)
at x (jquery.js?v=270:4:10802)
at XMLHttpRequest.<anonymous> (jquery.js?v=270:4:14767)
index.php:8411 parsererror
index.php:8412 SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at n.parseJSON (jquery.js?v=270:4:5309)
at vc (jquery.js?v=270:4:7397)
at x (jquery.js?v=270:4:10802)
at XMLHttpRequest.<anonymous> (jquery.js?v=270:4:14767)

问题分析

错误提示Unexpected token <说明第二次请求返回的不是合法JSON,而是HTML内容(通常是PHP的错误提示页面)。结合注释中"移除打印机代码后两次请求都正常"的信息,核心问题在于打印机端口9100是单连接端口,同一时间只能处理一个连接请求:第二次请求尝试创建NetworkPrintConnector时会触发PHP错误,错误信息以HTML格式输出(开头为<),破坏了JSON结构,导致前端解析失败。

解决方案

1. 捕获PHP错误,保证JSON输出完整性

在打印机相关代码外围添加try-catch,避免错误信息混入响应内容:

<?php
header('Access-Control-Allow-Origin: *');
header('Content-type: application/json');
$ticket = $_POST['m'];

$response['status'] = "ok";
try {
    $connector = new NetworkPrintConnector("192.168.1.5",9100);
    $printer = new Printer($connector);
    // 执行打印逻辑
} catch (Exception $e) {
    $response['status'] = "error";
    $response['message'] = $e->getMessage();
}

echo json_encode($response);
?>

2. 前端限制并发请求,改为串行调用

将test()包装为Promise,确保第一个请求完成后再发送第二个:

function test() {
    return new Promise((resolve, reject) => {
        const json = {"name" : {"name" : "test", "other" : 4} };
        $.ajax({
            type: "POST",
            url: "http://localhost:8080/print.php",
            data: {m:json, mm:"5"},
            dataType: 'json',
            cache: false,
            success: function(neu){
                console.log(neu.status);
                resolve(neu);
            },
            error: function( jqXHR, textStatus, errorThrown ) {
                console.log(textStatus);
                console.log(errorThrown);
                reject(errorThrown);
            }
        });
    });
}

// 串行执行两次请求
test().then(() => test()).catch(err => console.error(err));

3. 优化打印机连接逻辑

如果打印机支持,可在PHP中实现连接池复用已有的打印机连接;若打印机仅支持单连接,则需在服务端添加请求队列,排队处理打印任务。

内容的提问来源于stack exchange,提问作者nacho1111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 14:36:15