使用Formidable实现Node.js文件上传时files对象为空的问题排查
文件上传问题排查与修复
你遇到的Node.js端files对象为空的问题,主要由以下几个原因导致,对应修复方案如下:
1. 表单默认提交与Angular HTTP请求冲突
你的HTML表单包含<input type="submit"/>,点击时会触发浏览器默认表单提交行为,这会和Angular组件中handleFileInput里的http.post请求冲突:
- 选择文件时会触发
handleFileInput发送一次请求,但点击submit后,浏览器会自动发起另一个表单提交请求,可能导致Node端接收到的是未被正确处理的默认请求,甚至中断之前的Angular请求。
修复方式:
修改HTML,阻止表单默认提交,改用普通按钮触发上传:
<div class="app"> <form (ngSubmit)="$event.preventDefault()"> <input type="file" name="filetoupload" (change)="handleFileInput($event)"/> <br/> <br/> <button type="button" (click)="handleFileInput($event)">上传文件</button> </form> </div>
2. Node端未过滤请求路径与处理响应
当前Node服务器对所有请求都执行formidable解析,但Angular请求的是/fileupload路径,且解析完成后未结束响应,会导致请求挂起,同时可能错误解析其他路径的请求。
修复方式:
仅对POST /fileupload的请求进行解析,并在完成后返回响应:
const formidable = require('formidable'); const http = require('http'); http.createServer(function(req, res) { // 处理OPTIONS预检请求(解决跨域) if (req.method === 'OPTIONS') { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); res.writeHead(200); res.end(); return; } // 仅处理POST方法的/fileupload路径 if (req.method === 'POST' && req.url === '/fileupload') { const form = formidable({}); form.parse(req, (err, fields, files) => { if (err) { res.setHeader('Access-Control-Allow-Origin', '*'); res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('文件解析失败'); return; } console.log('接收到的文件:', files); // 返回成功响应 res.setHeader('Access-Control-Allow-Origin', '*'); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true, files: files })); }); } else { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('请求路径不存在'); } }).listen(8000);
3. Angular端响应类型配置不匹配
你设置了responseType: 'arraybuffer',但Node端返回的是JSON格式数据,这会导致客户端解析响应时出现异常,建议移除该配置(默认响应类型为JSON):
public handleFileInput(event) { console.log(event.target.files[0]); const formData = new FormData(); formData.append("thumbnail", event.target.files[0]); this.http.post(TGT_IP+'/fileupload', formData).subscribe( (val) => { console.log("POST call successful value returned in body", val); }, response => { console.log("POST call in error", response); }, () => { console.log("The POST observable is now completed."); }); }
4. 跨域问题处理
如果Angular应用运行端口与Node服务器的8000端口不同,必须在Node端添加CORS响应头,上述Node修复代码中已经包含了相关配置,可直接使用。
内容的提问来源于stack exchange,提问作者Zvi Vered
相关产品推荐
相关产品推荐

