【问题标题】:What is the best way to multiple file upload through a single input in nodejs express 4?通过nodejs express 4中的单个输入上传多个文件的最佳方法是什么?
【发布时间】:2018-11-06 16:23:22
【问题描述】:

我正在使用带有 express 4 的 nodejs。我正在尝试通过单个输入字段上传多个文件。我也通过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); 显示未定义。

【问题讨论】:

    标签: node.js express jquery-file-upload


    【解决方案1】:

    另一个完整的例子,也是迟到的答案;以防万一帮助某人。

    这不是基于 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”功能。

    **我认为如果你在另一个端口上运行上传脚本也会更好。


    上传.html

    <h3>{{msg}}</h3>
    <br/>
    <form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" multiple>
        <input type="submit">
    </form>
    

    【讨论】:

      【解决方案2】:

      经过不同类型的测试,我发现了问题。一切都很好,除非我上传单个文件。 当 ajax 发送单个文件时,它不是一个数组。这就是为什么长度未定义并且 forEach 没有运行的原因。需要先检查,然后使用 mv() 函数,比如 as-

      if(sampleFile instanceof Array){
          // here is the forEach block
      }else{
          // run a single mv() function
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        相关资源
        最近更新 更多