取消大文件上传请求后后续请求Pending的问题求助
解决取消大文件上传后后续请求Pending的问题
问题核心
你遇到的问题是:前端取消大文件上传请求后,后续所有HTTP请求均处于Pending状态无法完成;但无取消操作时,所有请求都能正常执行。且该现象在Axios、XHR、Superagent多个前端请求库中一致,说明问题根源大概率在后端Symfony 6的请求处理逻辑上。
可能的原因及对应解决方法
1. PHP-FPM进程未随客户端中断而终止
当用户取消上传时,前端主动断开了连接,但PHP-FPM进程可能还在持续读取上传的文件数据,导致进程被占用,无法处理新的请求。
解决方法:
- 确认
php.ini中ignore_user_abort = Off(默认值,但需检查是否被修改),确保客户端断开后PHP进程自动终止。 - 在Symfony的上传控制器中,主动检测连接状态,一旦发现客户端中断就终止处理:
public function uploadAction(Request $request) { // 处理上传前先检查连接状态 if (connection_aborted()) { return new JsonResponse(['msg' => '上传已取消'], 499); } // 处理文件上传逻辑,过程中周期性检查连接 $file = $request->files->get('file'); $stream = fopen($file->getPathname(), 'r'); while (!feof($stream)) { if (connection_aborted()) { fclose($stream); // 清理临时文件 unlink($file->getPathname()); return new JsonResponse(['msg' => '上传已取消'], 499); } // 分块读取处理 $chunk = fread($stream, 1024 * 1024); // 写入目标存储 } fclose($stream); return new JsonResponse(['msg' => '上传成功']); }
2. Symfony默认的请求解析阻塞了进程
Symfony在处理请求时,会先完整解析POST数据(包括上传文件)再进入控制器逻辑。如果文件很大,这个解析过程会持续很久,即使客户端取消连接,框架可能仍在继续读取数据,导致进程挂起。
解决方法:
- 使用流式上传绕过默认的请求解析,直接处理原始输入流:
use Symfony\Component\HttpFoundation\StreamedResponse; public function streamUploadAction(Request $request) { $inputStream = $request->getContent(true); // 获取可操作的流对象 $targetFile = fopen('/path/to/target/file', 'w'); while (!$inputStream->eof()) { if (connection_aborted()) { fclose($inputStream->detach()); fclose($targetFile); unlink('/path/to/target/file'); return new JsonResponse(['msg' => '上传取消'], 499); } $chunk = $inputStream->read(1024 * 1024); fwrite($targetFile, $chunk); } fclose($inputStream); fclose($targetFile); return new JsonResponse(['msg' => '上传成功']); } - 调整
php.ini参数:设置max_input_time = 300(根据业务需求调整),避免解析超时导致进程僵死。
3. Web服务器的连接复用问题
如果用Nginx/Apache做反向代理,取消上传后异常的连接可能被复用,导致后续请求无法正常发送到后端。
解决方法:
- 对于Nginx,配置合理的连接超时和复用规则:
server { # ... 其他配置 location / { proxy_pass http://127.0.0.1:9000; proxy_connect_timeout 10s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 限制每个连接的请求数,避免异常连接被重复使用 proxy_http_version 1.1; proxy_set_header Connection ""; } } - 检查Apache的
KeepAliveTimeout和MaxKeepAliveRequests参数,确保异常连接被及时回收。
验证步骤
- 先在上传控制器中添加
connection_aborted()检查,测试取消上传后进程是否立即终止; - 切换为流式上传方式,观察后续请求是否能正常完成;
- 查看PHP-FPM和Web服务器的日志,确认是否有进程阻塞或连接超时的记录,辅助定位问题。
内容的提问来源于stack exchange,提问作者Brayce
相关产品推荐
相关产品推荐

