8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Node/Express 文件上传

Thebest 2月前

99 0

我使用的是 node v0.10.26 和 express v4.2.0,我对 node 还很陌生。过去三个小时里,我一直在绞尽脑汁想办法让文件上传表单与 node 兼容。...

我使用的是 node v0.10.26 和 express v4.2.0,我对 node 还很陌生。过去三个小时里,我一直在绞尽脑汁尝试让文件上传表单与 node 配合使用。目前,我只是试图让 req.files 不返回未定义。我的视图如下所示

<!DOCTYPE html>
<html>
<head>
  <title>{{ title }}</title>
  <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
  <h1>{{ title }}</h1>
  <p>Welcome to {{ title }}</p>
  <form method='post' action='upload' enctype="multipart/form-data">
    <input type='file' name='fileUploaded'>
    <input type='submit'>
  </form>
</body>
</html>

这是我的路线

var express = require('express');
var router = express.Router();


/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Express' });
});

router.post('/upload', function(req, res){
console.log(req.files);
});

module.exports = router;

这是我的 app.js

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hjs');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});



module.exports = app;

我看到某个地方包括 methodOverride() bodyParser({keepExtensions:true,uploadDir:path}) 应该有所帮助,但如果我添加这些行,我甚至无法启动我的服务器。

帖子版权声明 1、本帖标题:Node/Express 文件上传
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Thebest在本站《express》版块原创发布, 转载请注明出处!
最新回复 (0)
  • const File = require("../models/file");
    const path = require('path');
    
    exports.localFileUpload = async (req, res) => {
      try {
        let sampleFile = req.files.sampleFile;
        console.log("File uploaded:", sampleFile);
    
        let uploadPath = path.join(__dirname, "/files", Date.now() + "_" + sampleFile.name);
        console.log("Upload path:", uploadPath);
    
        sampleFile.mv(uploadPath, function(err) {
          if (err) {
            console.log(err);
            return res.status(500).json({
              success: false,
            });
          }
        });
    
        return res.json({
          success: true,
          message: "File uploaded successfully"
        });
      } catch (error) {
        console.error(error);
        res.status(500).send({
          success: false,
          message: 'Server Error',
        });
      }
    }
    
    1. 、目录 __dirname 和具有当前时间戳和原始文件名的唯一文件名 /files 设置上传路径
    2. 使用 mv 方法将上传的文件移动到上传路径。记录错误并在失败时返回 500 状态和 JSON 响应。
  • 如果您正在使用 Node.js Express 和 Typescript,这里有一个工作示例,它也适用于 javascript,只需将 let 更改为 var 并将 import 更改为 includes 等...

    首先导入以下内容,通过运行以下命令确保安装 formidable:

    npm install formidable
    

    然后导入以下内容:

      import * as formidable from 'formidable';
      import * as fs from 'fs';
    

    然后你的功能如下:

        uploadFile(req, res) {
        let form = new formidable.IncomingForm();
        form.parse(req, function (err, fields, files) {
            let oldpath = files.file.path;
            let newpath = 'C:/test/' + files.file.name;
            fs.rename(oldpath, newpath, function (err) {
                if (err) throw err;
                res.write('File uploaded and moved!');
                res.end();
            });
        });
    }
    
  • 就我个人而言,我尝试了几个星期才搞定这个文件上传功能,但 multer 对我来说不起作用。然后我切换到 formidable,几天后,它完美地运行起来,没有任何错误,多个文件,express 和 react.js,尽管 react 是可选的。以下是指南: https://www.youtube.com/watch?v=jtCfvuMRsxE&t=122s

  • const http          = require('http');
    const fs            = require('fs');
    
    // https://www.npmjs.com/package/formidable
    const formidable    = require('formidable');
    
    // https://.com/questions/31317007/get-full-file-path-in-node-js
    const path          = require('path');
    
    router.post('/upload', (req, res) => {
        console.log(req.files);
    
        let oldpath = req.files.fileUploaded.path;
    
        // https://.com/questions/31317007/get-full-file-path-in-node-js       
        let newpath = path.resolve( `./${req.files.fileUploaded.name}` );
    
        // copy
        // https://.com/questions/43206198/what-does-the-exdev-cross-device-link-not-permitted-error-mean
        fs.copyFile( oldpath, newpath, (err) => {
    
            if (err) throw err;
    
            // delete
            fs.unlink( oldpath, (err) => {
    
                if (err) throw err;
    
                console.log('Success uploaded")
            } );                
    
        } );
    
    });
    
  • Multer 是一个用于处理 multipart/form-data 的 node.js 中间件,主要用于上传文件。它基于 busboy 编写,以实现最高效率。

  • Multer 是一个用于处理 multipart/form-data 的 node.js 中间件,主要用于上传文件。它基于 busboy 编写,以实现最高效率。

    npm install --save multer
    
    
    in app.js
    
        var multer  =   require('multer');
        var storage = multer.diskStorage({
          destination: function (req, file, callback) {
            callback(null, './public/uploads');
          },
          filename: function (req, file, callback) {
            console.log(file);
            callback(null, Date.now()+'-'+file.originalname)
          }
        });
    
        var upload = multer({storage: storage}).single('photo');
    
        router.route("/storedata").post(function(req, res, next){
    
            upload(req, res, function(err) {
              if(err) {
                console.log('Error Occured');
                return;
              }
              var userDetail = new mongoOp.User({
                'name':req.body.name,
                'email':req.body.email,
                'mobile':req.body.mobile,
                'address':req.body.address
              });
    
              console.log(req.file);
    
              res.end('Your File Uploaded');
              console.log('Photo Uploaded');
    
              userDetail.save(function(err,result){
              if (err) {
                return console.log(err)
              }
              console.log('saved to database') 
            })
          })
    
          res.redirect('/')
    
        });
    
  • 在 vanila node 中,我搞定了一些东西。只是一个快速上传服务器。不是花哨的 Express 东西。可能不是提问者想要的。

    const fs = require('fs'),
          http = require('http'),
          port = process.env.PORT || 9000,
          host = process.env.HOST || '127.0.0.1';
    //tested on node=v10.19.0, export HOST="192.168.0.103"
    http.createServer(function(req, res) {
    
      // Check if form is submitted and save its content
      if (req.method == "POST") try {
        store_file(req)
    
      // This is here incase any errors occur
      } catch (err) {
        res.writeHead(404);
        res.end('Server Borked');
        return;
      }
    
      // respond with a simple html form so they can post more data
      res.writeHead(200, {"content-type":"text/html; charset=utf-8"});
      res.end(`
    <form  method="post" enctype="multipart/form-data">
      <input type="file" name="fileUpload">
      <input type="submit" value="Upload">
    </form>`);
    }).listen(port, host, () => console.dir(`Serving at http://${host}:${port}`));
    
    function store_file(req) {
      // Generate temporary file name
      var temp = 'temp' + Math.floor(Math.random() * 10);
    
      // This opens up the writeable stream to temporary file
      var writeStream = fs.createWriteStream(temp);
    
      // This pipes the POST data to the file
      req.pipe(writeStream);
    
      // After the temporary file is creates, create real file
      writeStream.on('finish', () => {
    
        reader = fs.readFileSync(temp);
        filename = reader.slice(reader.indexOf("filename=\"") + "filename=\"".length, reader.indexOf('"\r\nContent-Type'));
        hash = reader.slice(0,reader.indexOf('\r\n'));
        content = reader.slice(reader.indexOf('\r\n\r\n') + '\r\n\r\n'.length, reader.lastIndexOf(Buffer.from('\r\n') + hash));
    
        // After real file is created, delete temporary file
        fs.writeFileSync(filename.toString(), content);
        fs.unlinkSync(temp);
      });
    }
    
  • 我需要比其他答案更详细地介绍一下(例如,如何将文件写入我在运行时决定的位置?)。希望这对其他人有所帮助:

    获取连接 busboy:

    npm install connect-busboy --save
    

    在你的 server.js 中,添加以下行

    let busboy = require('connect-busboy')
    
    // ... 
    
    app.use(busboy());
    
    // ... 
    
    app.post('/upload', function(req, res) {
        req.pipe(req.busboy);
        req.busboy.on('file', function(fieldname, file, filename) {
            var fstream = fs.createWriteStream('./images/' + filename); 
            file.pipe(fstream);
            fstream.on('close', function () {
                res.send('upload succeeded!');
            });
        });
    });
    

    但这似乎省略了错误处理...如果我找到它,我会对其进行编辑。

  • 引用 10

    您无法等待 fs.writeFile(),因为它不返回承诺。不过您可以等待 fs.promises.writeFile() - 但该方法不会接受回调,因为它会返回承诺。

  • 这是一个对我来说更简单的方法:

    const express = require('express');
    var app = express();
    var fs = require('fs');
    
    app.post('/upload', async function(req, res) {
    
      var file = JSON.parse(JSON.stringify(req.files))
    
      var file_name = file.file.name
    
      //if you want just the buffer format you can use it
      var buffer = new Buffer.from(file.file.data.data)
    
      //uncomment await if you want to do stuff after the file is created
    
      /*await*/
      fs.writeFile(file_name, buffer, async(err) => {
    
        console.log("Successfully Written to File.");
    
    
        // do what you want with the file it is in (__dirname + "/" + file_name)
    
        console.log("end  :  " + new Date())
    
        console.log(result_stt + "")
    
        fs.unlink(__dirname + "/" + file_name, () => {})
        res.send(result_stt)
      });
    
    
    });
    
  • Mick Cullen 的 答案 简化版本( 要点 ——部分是为了证明实现这一点并不需要太复杂;部分是为了给那些不想阅读大量代码的人提供快速参考。


    你必须让你的应用程序使用 connect-busboy :

    var busboy = require("connect-busboy");
    app.use(busboy());
    

    除非您触发它,否则它不会执行任何操作。在处理上传的调用中,执行以下操作:

    app.post("/upload", function(req, res) {
        if(req.busboy) {
            req.busboy.on("file", function(fieldName, fileStream, fileName, encoding, mimeType) {
                //Handle file stream here
            });
            return req.pipe(req.busboy);
        }
        //Something went wrong -- busboy was not loaded
    });
    

    让我们详细分析一下:

    • 检查是否 req.busboy 设置(中间件已正确加载)
    • 你设置了一个 "file" 监听器 req.busboy
    • 您将内容传输 req req.busboy

    文件监听器内部有几个有趣的东西,但真正重要的是 fileStream :这是一个 可读的 ,然后可以像平常一样将其写入文件。

    陷阱: 您必须处理这个可读性,否则 express 将永远不会响应请求 ,请参阅 busboy API 文件 部分)。

  • 如果在将 multer 函数传递给 app.use 时遇到问题,则可能需要进行如下设置 ``` var upload = multer({ dest: 'uploads/' }); var app = express() app.post('/profile', upload.single('field-name'), function (req, res, next) { console.log(req.file); }) ```

  • 抛出新的 TypeError('app.use() 需要中间件函数');

  • 在对未知字段错误感到沮丧后,我离开了 multer。我的代码中的所有内容都是正确的。它大多数时候都有效,然后神秘地显示此异常,而所有内容保持不变(环境、文件、代码、文件名)

  • 另一种选择是使用 multer ,它使用引擎盖下的 busboy,但设置更简单。

    var multer = require('multer');
    var upload = multer({dest: './uploads/'});
    

    您可以注册一个全局中间件并设置上传的目的地:

    app.use(upload.single('avatar'));
    

    然后,在任何您希望文件所在的 POST 中,您都可以访问数据:

    app.post('/', function(req, res) {
        // req.file (singular) is the file
        console.dir(req.file);
    });
    

    您可能只想在特定路由上设置它,而不是全局注册的中间件:

    app.post('/', upload.single('avatar'), function(req, res){
        console.dir(req.file);
    });
    

    其他中间件选项包括 fields , array ,和 none (用于纯文本多部分)。例如发送多个文件:

    app.post('/', uploads.array('photos', 12), function(req, res){
        // req.files (plural) is an array of files
        console.dir(req.files);
    });
    

    在视图中创建表单时, enctype='multipart/form-data multer 需要工作:

    form(role="form", action="/", method="post", enctype="multipart/form-data")
        div(class="form-group")
            label Upload File
            input(type="file", name="avatar", id="avatar")
    

    欲了解更多示例,请查看 github 页面。

  • 确保您的

    element has enctype="multipart/form-data". Otherwise req.files will be empty.
  • 这个答案是 Github 上给出的示例,但是查看存储库文件时,您会看到行 sampleFile.mv... 写为 uploadPath = __dirname + '/uploads/' + sampleFile.name; - 我发现这一点额外的澄清很有帮助 链接

  • 那些寻找具有最新 NPM 包的更新解决方案的人应该看看这里。express-fileupload 使这变得非常容易。

  • 引用 20

    我发现这个简单而有效:

    const express = require('express');
    const fileUpload = require('express-fileupload');
    const app = express();
    
    // default options
    app.use(fileUpload());
    
    app.post('/upload', function(req, res) {
      if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No files were uploaded.');
      }
    
      // The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
      let sampleFile = req.files.sampleFile;
    
      // Use the mv() method to place the file somewhere on your server
      sampleFile.mv('/somewhere/on/your/server/filename.jpg', function(err) {
        if (err)
          return res.status(500).send(err);
    
        res.send('File uploaded!');
      });
    });
    

    express-文件上传

返回
作者最近主题: