异常
当上传文件后浏览器显示:
{"errno":-4058,"code":"ENOENT","syscall":"open","path":"D:\\NodeJs\\node-demo\\upload\\img\\IMG1604419333167.jpg"}
而控制台也打印错误栈:
node:_http_outgoing:576
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:371:5)
at ServerResponse.setHeader (node:_http_outgoing:576:11)
at ServerResponse.header (D:\NodeJs\node-demo\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (D:\NodeJs\node-demo\node_modules\express\lib\response.js:170:12)
at D:\NodeJs\node-demo\upload.js:27:18
at D:\NodeJs\node-demo\node_modules\express-fileupload\lib\utilities.js:56:57
at WriteStream.<anonymous> (D:\NodeJs\node-demo\node_modules\express-fileupload\lib\utilities.js:181:29)
at WriteStream.emit (node:events:390:28)
at emitCloseNT (node:internal/streams/destroy:145:10)
at emitErrorCloseNT (node:internal/streams/destroy:130:3) {
code: 'ERR_HTTP_HEADERS_SENT'
}
Node.js v17.1.0
错误代码
// 第一步,引入express
var express = require("express");
// 引入文件上传模块express-fileupload
var fileUpload = require('express-fileupload');
// 第二步,创建服务器应用程序
var app = express();
// 配置文件上传模块
app.use(fileUpload());
app.post('/upload', function (request, response) {
var avatarFile = request.files.avatar;
console.log(avatarFile);
// 处理文件上传失败
if (!request.files || Object.keys(request.files).length === 0) {
return response.static(400).send("没有文件被上传!")
}
// 获取上传文件名
var fileName = avatarFile.name;// 注意avatar对应input标签的name属性值
// 设定文件的保存路径
var uploadPath = __dirname + "/upload/img/" + fileName;
// 使用mv方法来将上传文件保存到指定路径下
// mv(filePath, callback)有两个参数:filePath指定是上传文件的保存路径,callback是回调函数用来处理错误并且有一个参数err表示错误对象
avatarFile.mv(uploadPath, function (err) {
if (err)
return response.status(500).send(err);
response.send('文件上传成功!');
});
});
// 监听端口
app.listen(8989, function () {
console.log("app is running at port 8989.");
});
原因
实际上代码没有任何问题。具体原因可参考官网issue。
究其原因在于ar uploadPath = __dirname + "/upload/img/" + fileName;
这一行。
__dirname
表示当前js文件所在目录,肯定是存在的,但是/upload/img
这是一个目录,是我们要保存上传文件到的指定目录,但该目录不存在(即没有被创建),这就是导致上面问题的关键,我们必须手动创建这个目录,代码不会给你自动创建不存在的目录。fileName
表示上传文件的文件名。
解决
手动创建/upload/img
目录。