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
相关产品推荐
相关产品推荐

