【问题标题】:Nodejs server sometimes fails to upload files using multer, express, foreverNodejs服务器有时无法使用multer,express,永远上传文件
【发布时间】:2015-12-13 20:25:57
【问题描述】:

我正在尝试构建一个简单的文件服务器来接收来自带有 multipart/form-data 的 post 请求的文件,我按照 multer 教程进行操作,但似乎有些地方不太正确,它有时会返回 500 内部服务器错误。代码如下。

var express = require('express');
var multer  = require('multer');
var mkdirp = require('mkdirp');
var app = express();
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    var dir = 'file/' + req.body.jobid + '/';
    mkdirp(dir, function(err) {
        if(err) {
            console.error(err);
        }
    });
    cb(null, dir);
    console.log("Upload: saved to " + dir + file.originalname);
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  }
});

var upload = multer({ storage: storage });

app.post('/', upload.single("file"),function (req, res, next) {
  res.status(200).end();
  next(req,res);
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

错误发生在十个请求中每两个。

我曾经永远开始的代码

forever start app.js;

我是 nodejs 的新手,这种错误(偶尔发生的错误)正在杀死我。

我添加了一些函数来记录可能的错误。

app.use(function(err, req, res, next) {
  console.error(err.stack);
  next(err);
});

app.use(function(err, req, res, next) {
  if (req.xhr) {
    res.status(500).send({ error: err.stack });
  } else {
    next(err);
  }
});

它记录了如下内容:

Upload: saved to file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123
Error: ENOENT, open 'file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123'
    at Error (native)
Error: ENOENT, open 'file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123'
    at Error (native)

【问题讨论】:

    标签: node.js express forever multer


    【解决方案1】:

    可能发生的情况是,有时您的代码会抛出一个同步错误,默认情况下该错误会变成 500 响应。在不知道错误是什么的情况下很难诊断。您应该做的是在var server 之前添加一个错误处理程序,它将捕获错误并将它们记录到控制台。然后当错误发生时,您将能够轻松地看到它并解决问题。

    app.use(function(err, req, res, next) {
        console.log(err);
        next(err);
    });
    
    var server = app.listen(3000, function () {
      var host = server.address().address;
      var port = server.address().port;
    
      console.log('Example app listening at http://%s:%s', host, port);
    });
    

    编辑

    将cb(null, dir); 向上移动一行,如下所示:

    destination: function (req, file, cb) {
        var dir = 'file/' + req.body.jobid + '/';
        mkdirp(dir, function(err) {
            if(err) {
                console.error(err);
            }
            // move cb to here
            cb(null, dir);
        });
    
        console.log("Upload: saved to " + dir + file.originalname);
      },
      filename: function (req, file, cb) {
        cb(null, file.originalname);
      }
    

    【讨论】:

    • 您的代码似乎不起作用。它不断打印出所有的请求。我还有一个关于“下一个(错误);”的问题。为什么将错误传递给堆栈中的下一个函数?感谢您的宝贵时间。
    • 您是否将其复制到您的代码中?为了让它工作,函数需要恰好有 4 个参数(err、req、res、next),即使它们没有被函数使用。很多人都犯了这个错误,因为他们使用 ESlint 抱怨未使用的变量。它应该只打印出错误对象。如果它打印出每个请求,那么肯定有问题。
    • 我之所以调用 next(err) 是因为我现在不知道你想如何处理连接,而我真正关心的是记录它。所以我传递了err,以便 Express 可以处理它,并正确关闭连接。
    • 我使用了快速教程代码来捕获日志错误,它显示了类似这样的内容。上传:保存到文件/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123 错误:ENOENT,打开 'file/9974de5b-a9c7-4de2-92d0-5dcf277b3946/file123' at Error (native) 我想我应该把它包括在我的问题。
    • 问题似乎消失了。所以问题是在 mkdirp() 完成之前调用了 cb() 吗?非常感谢。
    猜你喜欢
    • 2015-03-09
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2021-05-03
    • 2018-04-23
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    相关资源
    最近更新 更多