通过nodejs express 4中的单个输入上传多个文件的最佳方法是什么?
What is the best way to multiple file upload through a single input in nodejs express 4?
我将 nodejs 与 express 4 一起使用。我正在尝试通过单个输入字段上传多个文件。我还通过 ajax 提交了我的表格。
我正在使用 express-fileupload 中间件上传文件。当我上传多个文件时,它工作正常。但是当上传单个文件时,它不起作用。
html代码-
<input type="file" name="attach_file" id="msg_file" multiple />
ajax代码-
var data = new FormData();
$.each($('#msg_file')[0].files, function(i, file) {
data.append('attach_file', file);
});
$.ajax({
url: '/send_message',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST',
success: function(data){
console.log(data);
}
});
服务端js代码-
router.post('/send_message', function(req, res, next){
if (!req.files)
res.json('No files were uploaded.');
let sampleFile = req.files.attach_file;
console.log(sampleFile.length);
var file_info = [];
var count = 0;
sampleFile.forEach(function(ele, key) {
ele.mv(path.resolve(`./public/upload/${ele.name}`), function(err) {
if (err){
console.log(err);
}else{
file_info.push(ele.name);
}
count++;
if(sampleFile.length == count){
res.json({file_name: file_info });
}
});
});
});
如果我上传单个文件 console.log(sampleFile.length);
显示未定义。
经过各种测试,我发现了问题。一切正常,除非我上传单个文件。
ajax发送单个文件时,不是数组。这就是为什么 length 未定义而 forEach 没有 运行 的原因。需要先检查,然后使用 mv() 函数,如 as-
if(sampleFile instanceof Array){
// here is the forEach block
}else{
// run a single mv() function
}
另一个完整的例子和迟到的答案;以防对某人有所帮助。
这不是ajax基础的;我在客户端使用了一个表单;但您可以使用 JS 和 XHR 发送数据。
它支持单个和多个上传。
upload.js
'use strict';
const fss = require('fs')
const pth = require('path');
const exp = require('express');
const swg = require('swig');
const efm = require("formidable");
const app = exp();
const thm = swg.compileFile(pth.join(__dirname, '', 'upload.html'));
app.listen(9009);
app.get(`/`, async (q, r) => r.send(thm({ msg: "Select a File to Upload" })));
app.get(`/:msg`, async (q, r) => r.send(thm({ msg: q.params.msg })));
app.post('/upload', (r, q) => {
const form = efm({ multiples: true });
form.parse(r, (e, p, files) => {
let dir = pth.join(__dirname, '', '/media/');
if (!fss.existsSync(dir)) fss.mkdirSync(dir);
let uploaded = 0, exists = 0, error = 0;
//if single file uploaded
if(!Array.isArray(files.file)){
files.file=[files.file]
}
files.file.forEach(f => {
let nPth = dir + f.name;
try {
fss.accessSync(nPth, fss.F_OK);
exists++;
} catch (file_e) {
let err = fss.renameSync(f.path, nPth);
if (err) error++; else uploaded++;
}
});
q.redirect(`Upoader -> All: ${files.file.length}, Uploaded: ${uploaded}, Existed: ${exists}, Error: ${error}`);
});
});
**最好使用“A-Sync”功能。
**我认为如果您 运行 在另一个端口上上传脚本会更好。
upload.html
<h3>{{msg}}</h3>
<br/>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" multiple>
<input type="submit">
</form>
我将 nodejs 与 express 4 一起使用。我正在尝试通过单个输入字段上传多个文件。我还通过 ajax 提交了我的表格。 我正在使用 express-fileupload 中间件上传文件。当我上传多个文件时,它工作正常。但是当上传单个文件时,它不起作用。 html代码-
<input type="file" name="attach_file" id="msg_file" multiple />
ajax代码-
var data = new FormData();
$.each($('#msg_file')[0].files, function(i, file) {
data.append('attach_file', file);
});
$.ajax({
url: '/send_message',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST',
success: function(data){
console.log(data);
}
});
服务端js代码-
router.post('/send_message', function(req, res, next){
if (!req.files)
res.json('No files were uploaded.');
let sampleFile = req.files.attach_file;
console.log(sampleFile.length);
var file_info = [];
var count = 0;
sampleFile.forEach(function(ele, key) {
ele.mv(path.resolve(`./public/upload/${ele.name}`), function(err) {
if (err){
console.log(err);
}else{
file_info.push(ele.name);
}
count++;
if(sampleFile.length == count){
res.json({file_name: file_info });
}
});
});
});
如果我上传单个文件 console.log(sampleFile.length);
显示未定义。
经过各种测试,我发现了问题。一切正常,除非我上传单个文件。 ajax发送单个文件时,不是数组。这就是为什么 length 未定义而 forEach 没有 运行 的原因。需要先检查,然后使用 mv() 函数,如 as-
if(sampleFile instanceof Array){
// here is the forEach block
}else{
// run a single mv() function
}
另一个完整的例子和迟到的答案;以防对某人有所帮助。
这不是ajax基础的;我在客户端使用了一个表单;但您可以使用 JS 和 XHR 发送数据。
它支持单个和多个上传。
upload.js
'use strict';
const fss = require('fs')
const pth = require('path');
const exp = require('express');
const swg = require('swig');
const efm = require("formidable");
const app = exp();
const thm = swg.compileFile(pth.join(__dirname, '', 'upload.html'));
app.listen(9009);
app.get(`/`, async (q, r) => r.send(thm({ msg: "Select a File to Upload" })));
app.get(`/:msg`, async (q, r) => r.send(thm({ msg: q.params.msg })));
app.post('/upload', (r, q) => {
const form = efm({ multiples: true });
form.parse(r, (e, p, files) => {
let dir = pth.join(__dirname, '', '/media/');
if (!fss.existsSync(dir)) fss.mkdirSync(dir);
let uploaded = 0, exists = 0, error = 0;
//if single file uploaded
if(!Array.isArray(files.file)){
files.file=[files.file]
}
files.file.forEach(f => {
let nPth = dir + f.name;
try {
fss.accessSync(nPth, fss.F_OK);
exists++;
} catch (file_e) {
let err = fss.renameSync(f.path, nPth);
if (err) error++; else uploaded++;
}
});
q.redirect(`Upoader -> All: ${files.file.length}, Uploaded: ${uploaded}, Existed: ${exists}, Error: ${error}`);
});
});
**最好使用“A-Sync”功能。
**我认为如果您 运行 在另一个端口上上传脚本会更好。
upload.html
<h3>{{msg}}</h3>
<br/>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" multiple>
<input type="submit">
</form>