首页 > 解决方案 > 如果大小太大,如何终止 node.js http 请求?

问题描述

如果用户的请求大于 8mb,我想终止 node.js 进程中的 http 服务器。我当前的代码似乎在基本测试中工作,但我不确定 res.end() 是否是异步的,并且可能在 process.exit() 完成之前被销毁。我在这里使用了 process.exit ,因为如果用户的请求大于 8mb,我不想在他们发送大量数据时让进程保持活动状态。

req.on('data', (chunk) => {
    body += chunk;
    if(body.length > 8000000) {
        res.writeHead(413, defaultHead);
        res.end('{"error":"Request exceeded 8mb maximum size."}');
        process.exit(0);
    }
});

标签: node.jshttpasynchronous

解决方案


你正在做的事情,它会起作用,因为同样的事情是由body-parser流行的包完成的,用于req.body在 express 中解析。

现在,它是怎么body-parser做的,它使用另一个名为 的包raw-body,它接受一个limit参数,如果当前块 > 限制它调用传递的回调。

  function onData (chunk) {
    if (complete) return

    received += chunk.length

    if (limit !== null && received > limit) {
      done(createError(413, 'request entity too large', {
        limit: limit,
        received: received,
        type: 'entity.too.large'
      }))
    } else if (decoder) {
      buffer += decoder.write(chunk)
    } else {
      buffer.push(chunk)
    }
  }

done是这里的回调,它会创建一个错误并将其作为回调中的第一个参数推送。

body-parser代码中:

getBody(stream, opts, function (error, body) {
  if (error) {
    var _error= createError(400, error)

    // read off entire request
    stream.resume()
    onFinished(req, function onfinished () {
      next(createError(400, _error))
    })
    return
  }

  ....
  next()
})

如果出现错误,它只是使用读取整个流stream.resume()并传递错误。所以基本上你是在复制一个简单的版本,理论上应该可以工作。

注意,onFinished是另一个在 HTTP 请求关闭、完成或错误时执行回调的包。


推荐阅读