Apache环境下XHR请求PHP端点:本地正常线上报500与JSON解析异常排查
问题场景
- 技术栈:Apache 服务器承载后端 PHP 接口,前端通过 JS 捕获表单数据、使用 XHR 完成和后端的交互
- 异常表现:本地运行时代码功能完全正常,部署到生产站点后同时出现两类错误:
- 接口返回
500 Internal Server Error - 前端控制台抛出未捕获语法错误
unexpected end of JSON input(JSON输入意外结束),错误定位在 XHR 的onload回调中
- 接口返回
- DevTools 定位信息:500 状态的报错点对应
index.js第 18 行代码
相关代码片段
前端 XHR 逻辑(index.js)
var xhr = new XMLHttpRequest(); xhr.open('POST', submitUrl, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = () => { // 语法错误触发位置:解析响应时拿到空内容 var response = JSON.parse(xhr.responseText); console.log(response); if (response.error === 'member-exists') { setAlreadySubscribed(); showStatusAndHideForm(); } else if (response.error === 'none') { setSuccess(); showStatusAndHideForm(); } else { alertUnknownError(); enableForm(); } } xhr.send(body);
错误关联逻辑:后端返回 500 错误时,由于生产环境 PHP 配置通常关闭错误显示,返回给前端的响应体往往是空字符串;前端拿到空字符串直接执行
JSON.parse()时,就会触发「JSON 输入意外结束」的语法错误。
后端接口逻辑(submitUrl.php)
$ch = curl_init('https://foo'); curl_setopt_array($ch, array( CURLOPT_POST => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPHEADER => array( 'Authorization: apikey '.$authToken, 'Content-Type: application/json' ), CURLOPT_POSTFIELDS => $userdata ), ); $result = curl_exec($ch);
后端流程说明:拿到 cURL 请求返回的
$result后,会先解码校验外部 API 返回的错误信息,再将处理结果编码为 JSON 回传给前端 XHR。
常见触发原因
- 生产环境 PHP 环境配置与本地不一致:比如生产服务器未启用 cURL 扩展,调用
curl_init()时直接触发致命错误,PHP 中断执行后返回空的 500 响应 - 生产环境未对未定义变量做兼容:比如
$authToken、$userdata依赖的配置文件加载路径在生产环境错误,变量处于未定义状态,调用时触发 PHP 警告/致命错误,中断流程 - cURL 请求在生产网络环境下执行失败:比如生产服务器无法连通外部目标接口、SSL 证书校验不通过、请求超时,
curl_exec()返回布尔值false后,后续代码未做错误判断直接执行 JSON 解码等操作,触发致命错误 - PHP 输出配置不规范:生产环境未强制设置 JSON 响应头,PHP 触发 warning 级别的错误时会把错误文本直接输出在响应体中,既破坏原本要返回的 JSON 结构,也会因为流程中断返回 500 状态
- PHP 版本差异导致代码兼容问题:本地和生产的 PHP 版本不一致,本地支持的语法、隐式类型转换逻辑在生产版本中触发解析错误,直接返回空的 500 响应
内容的提问来源于stack exchange,提问作者rachel wagschal
相关产品推荐
相关产品推荐

