使用Node.js,Express和Mongoose上传图像

Joh*_*len 102 file-upload image mongoose node.js express

随着事情多年来的变化,请考虑更新的答案,这些答案包含更多最新信息!

由于许多新的Node.js库很快就被淘汰了,而且我想要询问有关使用以下内容上传图像的例子相对较少:

  • Node.js(v0.4.1)
  • 快递(1.0.7)
  • 猫鼬(1.1.0).

别人怎么做的?

我发现:node-formidable,但我不熟悉上传图片,所以我想学习一般的东西以及使用Node.js和Express这样做的方法.

Joh*_*len 75

我第一次回答我自己的问题.我直接从源头找到了一个例子.请原谅可怜的缩进.复制和粘贴时我不确定如何正确缩进.代码直接来自GitHub上的Express multipart/form-data示例.

// Expose modules in ./support for demo purposes
require.paths.unshift(__dirname + '/../../support');

/**
 * Module dependencies.
 */

var express = require('../../lib/express')
  , form = require('connect-form');

var app = express.createServer(
  // connect-form (http://github.com/visionmedia/connect-form)
  // middleware uses the formidable middleware to parse urlencoded
  // and multipart form data
  form({ keepExtensions: true })
);

app.get('/', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Image: <input type="file" name="image" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});

app.post('/', function(req, res, next){

  // connect-form adds the req.form object
  // we can (optionally) define onComplete, passing
  // the exception (if any) fields parsed, and files parsed
  req.form.complete(function(err, fields, files){
    if (err) {
      next(err);
    } else {
      console.log('\nuploaded %s to %s'
        ,  files.image.filename
        , files.image.path);
      res.redirect('back');
    }
  });

  // We can add listeners for several form
  // events such as "progress"
  req.form.on('progress', function(bytesReceived, bytesExpected){
    var percent = (bytesReceived / bytesExpected * 100) | 0;
    process.stdout.write('Uploading: %' + percent + '\r');
  });
});

app.listen(3000);
console.log('Express app started on port 3000');
Run Code Online (Sandbox Code Playgroud)

  • @Luc:你没有,它被保存到一个临时目录,你将它移动到其他地方. (4认同)
  • 是的,但是你如何保存文件? (2认同)

Bre*_*ust 47

既然你正在使用express,只需添加bodyParser:

app.use(express.bodyParser());
Run Code Online (Sandbox Code Playgroud)

然后您的路线将自动访问req.files中上传的文件:

app.post('/todo/create', function (req, res) {
    // TODO: move and rename the file using req.files.path & .name)
    res.send(console.dir(req.files));  // DEBUG: display available fields
});
Run Code Online (Sandbox Code Playgroud)

如果你像这样命名输入控件"todo"(在Jade中):

form(action="/todo/create", method="POST", enctype="multipart/form-data")
    input(type='file', name='todo')
    button(type='submit') New
Run Code Online (Sandbox Code Playgroud)

然后,当您获取'files.todo'中的路径和原始文件名时,上传的文件就准备好了:

  • req.files.todo.path,和
  • req.files.todo.name

其他有用的req.files属性:

  • 大小(以字节为单位)
  • 类型(例如,'image/png')
  • lastModifiedate
  • _writeStream.encoding(例如,'binary')


srq*_*inn 19

您可以在主应用程序文件的配置块中配置连接主体解析器中间件:

    /** Form Handling */
    app.use(express.bodyParser({
        uploadDir: '/tmp/uploads',
        keepExtensions: true
    }))
    app.use(express.limit('5mb'));
Run Code Online (Sandbox Code Playgroud)

  • @AksharPrabhuDesai是和否.假设您有照片上传/裁剪工具.如果您允许用户直接上传到您的公用文件夹,则存在严重的安全漏洞.在这种情况下,最好上传到tmp文件夹,然后在确认文件不是特洛伊木马后移动到您的公用文件夹. (2认同)

Nil*_*esh 14

看,你能做的最好的事情就是将图像上传到磁盘并将URL保存在MongoDB中.再次检索图像时休息.只需指定URL,即可获得图像.上传代码如下.

app.post('/upload', function(req, res) {
    // Get the temporary location of the file
    var tmp_path = req.files.thumbnail.path;
    // Set where the file should actually exists - in this case it is in the "images" directory.
    target_path = '/tmp/' + req.files.thumbnail.name;
    // Move the file from the temporary location to the intended location
    fs.rename(tmp_path, target_path, function(err) {
        if (err)
            throw err;
        // Delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files.
        fs.unlink(tmp_path, function() {
            if (err)
                throw err;
            //
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

现在将目标路径保存在MongoDB数据库中.

同样,在检索图像时,只需从MongoDB数据库中提取URL,然后在此方法上使用它.

fs.readFile(target_path, "binary", function(error, file) {
    if(error) {
        res.writeHead(500, {"Content-Type": "text/plain"});
        res.write(error + "\n");
        res.end();
    }
    else {
        res.writeHead(200, {"Content-Type": "image/png"});
        res.write(file, "binary");
    }
});
Run Code Online (Sandbox Code Playgroud)


Dar*_*mid 9

试试这个代码.它会有所帮助.

app.get('/photos/new', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Data: <input type="filename" name="filename" /></p>'
    + '<p>file: <input type="file" name="file" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});


 app.post('/photos/new', function(req, res) {
  req.form.complete(function(err, fields, files) {
    if(err) {
      next(err);
    } else {
      ins = fs.createReadStream(files.photo.path);
      ous = fs.createWriteStream(__dirname + '/directory were u want to store image/' + files.photo.filename);
      util.pump(ins, ous, function(err) {
        if(err) {
          next(err);
        } else {
          res.redirect('/photos');
        }
      });
      //console.log('\nUploaded %s to %s', files.photo.filename, files.photo.path);
      //res.send('Uploaded ' + files.photo.filename + ' to ' + files.photo.path);
    }
  });
});

if (!module.parent) {
  app.listen(8000);
  console.log("Express server listening on port %d, log on to http://127.0.0.1:8000", app.address().port);
}
Run Code Online (Sandbox Code Playgroud)


小智 8

您还可以使用以下内容设置保存文件的路径.

req.form.uploadDir = "<path>";
Run Code Online (Sandbox Code Playgroud)


小智 5

创建了一个使用Express和Multer的示例.它非常简单,避免了所有连接警告

这可能会对某人有所帮助.