如何在Nodejs中实现文件上传前的大小检测?

如何在Nodejs中实现文件上传前的大小检测?

例如我想做一个文件上传的接口,这个接口限制文件上传大小不能超过1字节(这里只是举例说明才设这么小),Express代码如下:

app.post( '/upload' , function ( req , res ) {
    if ( req.header( 'content-length' ) > 1 ) {
        res.send( 'limit' );
    } else {
        res.send( 'ok' );
    }
} );

然后我上传了一个2GB的文件,使用Chrome的网络面板查看时,发现时间线里面Sending花了近15秒,也就是说,这个我不会保存的文件占用了服务端15秒的时间来处理,这实在太浪费了,15秒以后,才从服务端返回了“limit”

这样显然是不行的。要怎么做,才能在文件上传前就能检测它的大小,一旦发现超过1字节,那服务端就立刻返回呢?

这个问题的关注点在后端,前端验证方案不在讨论之列。


5 回复

要解决文件上传过程中占用服务器资源的问题,并且在文件上传之前就检测其大小,可以利用中间件来拦截请求并检查 Content-Length 头信息。此外,为了更准确地处理文件上传过程中的大小限制问题,可以使用专门的库如 multer 来处理文件上传,同时结合自定义逻辑来限制文件大小。

示例代码

首先,安装必要的依赖:

npm install express multer

接下来,创建一个简单的 Express 应用,并使用 multer 来处理文件上传:

const express = require('express');
const multer = require('multer');

const app = express();
const upload = multer({ dest: 'uploads/' });

// 设置文件大小限制
const maxSize = 1 * 1024; // 1字节

app.post('/upload', upload.single('file'), (req, res, next) => {
    const fileSize = req.file.size;
    
    if (fileSize > maxSize) {
        return res.status(400).send('File size exceeds the limit');
    }
    next();
}, (req, res) => {
    res.send('File uploaded successfully');
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. Multer 中间件multer 是一个专门用于处理 multipart/form-data 的中间件,通常用于上传文件。我们使用它来处理文件上传,并将其存储到指定目录。

  2. 设置文件大小限制:通过设置 maxSize 变量,我们可以定义允许的最大文件大小。在这个例子中,我们将大小限制为 1 字节。

  3. 中间件处理:在实际处理文件上传之前,我们添加了一个中间件来检查文件大小。如果文件大小超过限制,我们立即返回错误响应,避免进一步处理。

  4. 文件上传成功:如果文件大小符合要求,我们继续执行下一个中间件,并最终返回成功的响应。

通过这种方式,可以在文件上传之前就进行大小检查,从而避免不必要的资源消耗。


不能超过一个字节,那传什么? 楼主可以看下HTML5 中的 File API。 有对应的size属性。:)

这里的1字节只是作为一个例子。 另外,前端验证很容易绕过的,我需要的是一个服务端的解决方案

为了在文件上传前进行大小检测,以避免不必要的资源消耗,可以利用中间件在请求被完全读取之前判断文件大小。你可以使用express结合busboymulter这样的中间件来实现这一功能。以下是使用multer的示例代码,multer是一个专门用于处理multipart/form-data的中间件,常用于文件上传。

示例代码

首先安装multer

npm install multer

然后创建一个简单的Express服务器并配置multer

const express = require('express');
const multer = require('multer');

const app = express();

// 配置 multer 存储策略
const upload = multer({
  limits: { fileSize: 1 }, // 设置文件大小上限为 1 字节
  fileFilter(req, file, cb) {
    if (file.size > 1) {
      return cb(new Error('File size too large'));
    }
    cb(null, true);
  },
});

app.post('/upload', upload.single('file'), (req, res) => {
  res.send('File uploaded successfully.');
}, (err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    res.status(400).send('File size exceeds limit');
  } else {
    res.status(500).send('Internal Server Error');
  }
});

app.listen(3000, () => console.log('Server is running on port 3000'));

解释

  • multer通过limits选项设置文件大小限制。
  • fileFilter函数用于过滤不符合条件的文件,在文件大小超过限制时抛出错误。
  • 如果文件大小超出限制,multer会中断请求处理流程,并调用错误处理中间件发送响应,从而避免了长时间占用服务器资源。

这种方法确保了只有符合大小限制的文件才会被进一步处理,从而提高了服务器效率。

回到顶部