XHR上传PDF文件时PHP端接收空表单问题排查
XHR异步上传PDF时PHP端$_POST为空的排查方案
复现现象
- 基于
XMLHttpRequest+FormData实现的无刷新文件上传逻辑,上传图片时运行正常,PHP端可正常读取$_POST中的CSRF令牌、$_FILES中的文件数据 - 切换上传PDF文件时,PHP端打印
$_POST返回空数组,无法获取任何请求参数,功能异常 - 前端核心代码如下:
function uploadFile() { const files = document.getElementById("file").files; if(files.length > 0 ){ const formData = new FormData(); formData.append("file", files[0]); formData.append('__csrf', document.getElementById('csrf_profile').value); const xhr = new XMLHttpRequest(); // 设置请求方法与接口地址 xhr.open("POST", "/api/user/background", true); xhr.onreadystatechange = function() { if (this.readyState === 4) { const response = JSON.parse(this.responseText); if(response.status === true){ document.getElementById('message').innerText = 'cover image has been updated'; // 注意此处原有笔误:main-colo 应为 main-color,会导致成功状态文字颜色不生效 document.getElementById('message').style.color = 'var(--main-color)'; reloadPage(); }else{ document.getElementById('message').innerText = response.message; document.getElementById('message').style.color = '#F00'; } } }; xhr.send(formData); }else{ document.getElementById('message').innerText = "Please select a file"; document.getElementById('message').style.color = '#F00'; } }
- 后端调试代码:
die(print_r($_POST,true));
- 测试结果:上传图片输出
Array ( [__csrf] => token ),上传PDF输出空数组Array ( )
核心故障原因(90%概率为上传大小限制触发)
当POST请求整体大小、单文件大小超过服务端配置的阈值时,PHP会直接丢弃整个请求的表单数据,不会填充$_POST和$_FILES数组,就会出现你遇到的空数组问题。图片通常体积较小不会触发限制,PDF很容易超过默认的大小阈值。
按以下优先级逐一排查即可:
- 检查PHP上传相关配置
打开php.ini文件调整以下配置值,保证配置大小大于你需要上传的PDF文件体积:
修改完成后重启php-fpm(或对应PHP运行进程)让配置生效。; 整个POST请求的最大允许体积,建议设置为64M及以上 post_max_size = 64M ; 单个上传文件的最大允许体积,建议设置为32M及以上 upload_max_filesize = 32M ; PHP内存限制,数值需要大于上述两个配置 memory_limit = 128M - 检查Web服务器层上传限制
如果用Nginx作为Web服务器,需要在站点配置中调整client_max_body_size,数值和PHP的post_max_size保持一致即可:
修改后执行重载配置命令让规则生效。如果用Apache,需要检查client_max_body_size 64M;LimitRequestBody配置是否过小。 - 排除前端请求头配置错误
注意不要手动给XHR设置Content-Type: multipart/form-data请求头,浏览器会自动生成带随机boundary分隔符的合法请求头,手动设置会丢失分隔符导致后端无法解析表单数据。你当前的前端代码没有手动设置该头,这部分逻辑是正确的。
快速验证方法
- 先找一个体积小于2MB的小型PDF文件测试上传,如果此时后端能正常获取到
__csrf参数,可直接确认是大小限制问题,调整上述配置即可 - 如果小PDF依然上传失败,打开浏览器开发者工具-网络面板,查看上传请求的状态码:
- 状态码为413时,直接调整Web服务器的上传大小限制
- 状态码为200但参数为空,可额外打印
$_FILES数组,根据返回的上传错误码对应排查问题即可
内容的提问来源于stack exchange,提问作者mohamd Agoumi
相关产品推荐
相关产品推荐

