formidable.Files文件问题:抛出ERR_INVALID_ARG_TYPE错误求助
问题排查:Formidable 文件上传路径错误
问题描述
学习W3Schools教程时,尝试修改上传文件的存储路径,但直接使用教程代码无法运行,怀疑是API语法变更。尝试将filepath改为path后,files.filetoupload.filepath返回undefined,导致无法修改文件目录,抛出类型错误。
错误信息
Error code is: 'ERR_INVALID_ARG_TYPE'
throw new ERR_INVALID_ARG_TYPE(propName, ['string', 'Buffer', 'URL'], path);
TypeError [ERR_INVALID_ARG_TYPE]: The "oldPath" argument must be of type string or an instance of Buffer or URL.
环境版本
Node version:Node.js v18.12.1. Formidable version:8.19.2.
使用代码
var http = require('http'); var formidable = require('formidable'); var fs = require('fs'); http.createServer(function (req, res) { if (req.url == '/fileupload') { var form = new formidable.IncomingForm(); form.parse(req, function (err, fields, files) { var oldpath = files.filetoupload.filepath; var newpath = 'C:/Users/Your Name/' + files.filetoupload.originalFilename; fs.rename(oldpath, newpath, function (err) { if (err) throw err; res.write('File uploaded and moved!'); res.end(); }); }); } else { res.writeHead(200, {'Content-Type': 'text/html'}); res.write('<form action="fileupload" method="post" enctype="multipart/form-data">'); res.write('<input type="file" name="filetoupload"><br>'); res.write('<input type="submit">'); res.write('</form>'); return res.end(); } }).listen(8080);
问题原因及解决方法
- 核心问题:Formidable v3+ 版本对文件对象的属性做了变更,旧版本中的
filepath(或path)属性已被移除,取而代之的是文件对象自身的path属性。 - 修复步骤:
- 访问文件临时路径时,直接使用
files.filetoupload.path,这里的files.filetoupload是文件对象,其自身的path属性才是临时文件路径。 - Formidable v3+ 默认会自动清理临时文件,若需要手动移动文件,需先禁用自动清理,或使用
fs.copyFile替代fs.rename,避免跨磁盘分区的rename失败问题。
- 访问文件临时路径时,直接使用
修正后的代码示例
var http = require('http'); var formidable = require('formidable'); var fs = require('fs'); var path = require('path'); http.createServer(function (req, res) { if (req.url == '/fileupload') { var form = new formidable.IncomingForm(); // 保留文件扩展名,避免临时文件无后缀 form.keepExtensions = true; form.parse(req, function (err, fields, files) { if (err) { res.write('Error parsing form: ' + err.message); return res.end(); } // 获取临时文件路径 var oldpath = files.filetoupload.path; // 目标路径,替换为你的实际目录 var newpath = path.join('C:/Users/Your Name/', files.filetoupload.originalFilename); // 使用copyFile替代rename,兼容跨分区场景 fs.copyFile(oldpath, newpath, function (err) { if (err) { res.write('Error moving file: ' + err.message); return res.end(); } // 复制完成后删除临时文件 fs.unlink(oldpath, function(unlinkErr) { if (unlinkErr) console.error('Failed to delete temp file:', unlinkErr); }); res.write('File uploaded and moved!'); res.end(); }); }); } else { res.writeHead(200, {'Content-Type': 'text/html'}); res.write('<form action="fileupload" method="post" enctype="multipart/form-data">'); res.write('<input type="file" name="filetoupload"><br>'); res.write('<input type="submit">'); res.write('</form>'); return res.end(); } }).listen(8080);
额外说明
- Formidable v3+ 的文件对象结构与旧版本差异较大,需以当前版本的属性字段为准。
fs.copyFile比fs.rename更可靠,因为rename在跨磁盘分区时会失败,而copyFile可以处理该场景,之后手动删除临时文件即可。
内容的提问来源于stack exchange,提问作者Bartosz Stpiczynski
相关产品推荐
相关产品推荐

