【问题标题】:Node.js: how to limit the HTTP request size and upload file size?Node.js:如何限制 HTTP 请求大小和上传文件大小?
【发布时间】:2012-02-21 10:16:12
【问题描述】:

我正在使用 Node.js 和 express。

我想限制 HTTP 请求的大小。比方说,如果有人向我发送超过 2 MB 的 HTTP 请求,那么我会立即停止该请求。我看了看代码,我想如果我改变核心,我就可以做到。但是,有没有办法设置max_request_size 或类似的东西?

这与我的第二个问题有关。我正在使用 express 从req.files 获取上传的文件。一旦文件大小超过一定的文件大小,有没有办法停止将文件写入/tmp 文件夹(这是默认上传行为)?

【问题讨论】:

    标签: node.js file-upload size express http-request


    【解决方案1】:

    只是一个更新(07-2014),因为我无法添加 cmets:

    如上所述,较新的 Express 版本已弃用 limit 中间件,现在将其作为 BodyParser 中间件的 built-in option 提供:

       var express    = require('express')
       var bodyParser = require('body-parser')
    
       var app = express()
       app.use(bodyParser.json({ limit: '5mb' }))
    

    【讨论】:

    • 这就是我需要的。谢谢。
    • 在请求模块的情况下如何增加限制
    • 如果请求的大小不在正文中怎么办? :(如果有人开始发送 50Mb GET 请求怎么办?:(
    • 任何不在正文中的内容都将在标头中,并且 NodeJS 设置了最大标头大小的默认限制。例如,在 NodeJS 版本 11.6.0 中,限制为 8kb。 nodejs.org/api/http.html#http_http_maxheadersize
    • 我将如何将它与 react js 一起使用?
    【解决方案2】:

    Express 使用 Connect,它有 a limit middleware available。您可以通过执行以下操作在您的 Express 应用中使用它:

    app.use(express.limit('2mb'));
    

    例如,这会将所有 HTTP 请求限制为 2 MB。由于上传的文件是 HTTP 请求的一部分,因此任何大于 2 MB 的文件上传也会被中止。


    注意:此中间件已弃用,很快将被删除。有关为什么会这样的讨论,请访问:https://github.com/senchalabs/connect/pull/925#issuecomment-26990726

    【讨论】:

    • 如果我限制为 2MB,并通过 1GB 的 http 请求发送。如果超过 2MB,它会立即停止吗?还是返回错误但仍然获得剩余的 0.998GB 数据?
    • 源代码位于github.com/senchalabs/connect/blob/master/lib/middleware/…。如果我没看错,它会读取分块数据并在超过大小限制后立即终止请求。
    • express.limit 作为中间件在 nodejs 6 上已弃用
    【解决方案3】:

    节点github源码:

    /* Maximium header size allowed. If the macro is not defined
     * before including this header then the default is used. To
     * change the maximum header size, define the macro in the build
     * environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
     * the effective limit on the size of the header, define the macro
     * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
     */
    #ifndef HTTP_MAX_HEADER_SIZE
    # define HTTP_MAX_HEADER_SIZE (80*1024)
    #endif 
    

    所以,你需要从源头重建节点以超过 80*1024 的限制

    您可以将它与 Express 4 一起使用来限制请求正文大小/上传文件大小,而不是 express.json() 和 express.urlencoded(),您必须要求 body-parser 模块并使用它的 json() 和 urlencoded () 方法,如果没有为 bodyParser.urlencoded() 显式定义扩展选项,它会抛出一个警告(body-parser deprecated undefined extended:提供扩展选项)。

    var bodyParser = require('body-parser');
    app.use(bodyParser.json({limit: '50mb'}));
    app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
    

    【讨论】:

    • 问题 #1(以及我在赏金中的重点)是关于请求大小的。但是您的答案是关于请求正文的大小。 bodyParser 文档中明确提到限制参数“控制最大请求正文大小”。
    • 节点 github 的源代码:/* 允许的最大标头大小。如果在包含此标头之前未定义宏 * 则使用默认值。要 * 更改最大标头大小,请在构建 * 环境中定义宏(例如 -DHTTP_MAX_HEADER_SIZE=)。要删除 * 对标头大小的有效限制,请将宏 * 定义为一个非常大的数字(例如 -DHTTP_MAX_HEADER_SIZE=0x7fffffff)*/ #ifndef HTTP_MAX_HEADER_SIZE #define HTTP_MAX_HEADER_SIZE (80*1024) #endif ... 所以,你需要从源重建节点以超过 80*1024 的限制
    【解决方案4】:

    对于未弃用的更新解决方案,您可以像这样在 app.js 文件中添加限制:

    app.use(express.json({limit: '2mb'}));
    app.use(express.urlencoded({limit: '2mb', extended: false}));
    

    你也可以这样做:

    app.use(express.json({limit: 2000000}));
    app.use(express.urlencoded({limit: 2000000, extended: false}));
    

    【讨论】:

      【解决方案5】:
      var methodOverride = require('method-override');
      app.use(bodyParser.urlencoded({
              extended: true, limit: '50mb'
          }));
      app.use(bodyParser.json({limit: '50mb'}));
      app.use(methodOverride());
      

      【讨论】:

        【解决方案6】:

        使用raw-body。大多数中间件(如 limit)不再与 Express 捆绑在一起,必须单独安装。这是一个例子。

        var getRawBody = require('raw-body')
        app.use(function (req, res, next) {
              getRawBody(
                stream = req,
                options = {
                  length: req.headers['content-length'],
                  limit: '100mb',
                },
                callback = function (err, reslt) {
                  if (err) {
                    return next(err)
                  }
                  next();
                  console.log(req)
                })
            })
        
        • 记得在app.use后面加上路由器

        Express 不再允许您使用传统的捆绑中间件显式设置限制,如下所示。

        app.use(express.limit('4M'));
        

        【讨论】:

          【解决方案7】:

          问题 1 的答案

          要限制 HTTP 请求大小和上传文件大小,我们需要设置 body-parser 限制。

          app.use(bodyParser.urlencoded({limit: '50mb',extended: true}));
          app.use(bodyParser.json({limit: '50mb'}));
          

          bodyParser.urlencoded

          来自前端的文件以 urlencoded 的形式出现。

          返回仅解析 urlencoded 正文的中间件。此解析器仅接受正文的 UTF-8 编码,并支持 gzip 和 deflate 编码的自动膨胀。

          一个包含解析数据的新主体对象填充在中间件之后的请求对象上(即req.body)。该对象将包含键值对,其中值可以是字符串或数组(当扩展为假时)或任何类型(当扩展为真时)。

          bodyParser.json

          返回只解析 json 的中间件。此解析器接受正文的任何​​ Unicode 编码,并支持 gzip 和 deflate 编码的自动膨胀。

          在中间件之后的请求对象上填充一个包含解析数据的新主体对象(即 req.body)。

          注意: 默认情况下,正文解析器的输入限制为100kb

          问题 2 的答案

          要更改默认上传目录,我们可以使用以下内容。

          app.set('uploadDir', './files');  // Sets the upload Directory to files folder in your project.
          

          其他实现

          在将 bodyParser 包含到应用程序中时,我们可以提及上传目录。

          app.use(express.bodyParser({uploadDir:'./files', keepExtensions: true}));
          

          参考

          问题https://github.com/expressjs/express/issues/1684

          希望这会有所帮助!

          【讨论】:

          • 问题 #1(以及我在赏金中的重点)是关于 request 的大小。但你的答案是关于 request body 的大小。您提供的参考链接中明确提到了它:“控制最大请求正文大小。”
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-26
          • 2022-10-26
          • 1970-01-01
          • 2019-12-20
          • 1970-01-01
          • 2019-07-07
          • 2014-08-13
          相关资源
          最近更新 更多