1

我从浏览器获取“POST”值到 nodejs 和 express。
我将文件发布到nodejs。
下面是代码。

var express = require('express')
  , routes = require('./routes')
  , http = require('http');

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  //app.use(express.bodyParser());
  app.use(express.bodyParser({
      uploadDir: __dirname + '/upload',
      keepExtensions: true,
      limit: '50mb'
    }));
  app.use(express.limit('35mb'));
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});


app.post('/', function(request, response){

    console.log(request.body.upfile);
    console.log(request.files);
    var ret = {a:'a',b:'b'};
    response.writeHead(200, { 'Content-Type': 'application/json'});
    response.write(JSON.stringify(ret));
    response.end();

});

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

它可以接收发布文件。
但我已将文件大小限制设置为 50mb。
当我发布大于 50mb 的文件时。
浏览器将继续上传文件,直到完成。
我需要的是大于 50mb 的大小。它向浏览器响应 413(请求实体太大,这就是快速错误打印出来的内容)http 代码,阻止它上传。

我已经调查了 express 源代码。
它使用位于
第 45 行的 node_modules/express/node_modules/connect/lib/middleware/limit.js 中的连接
。它将 413 和调用堆栈记录到 stdio。
我想我可以在这里使用 413 http 代码来响应浏览器。
但是当我测试它时。浏览器打印重置。
下面是修改代码。

module.exports = function limit(bytes){
  if ('string' == typeof bytes) bytes = utils.parseBytes(bytes);
  if ('number' != typeof bytes) throw new Error('limit() bytes required');
  return function limit(req, res, next){
    var received = 0
      , len = req.headers['content-length']
        ? parseInt(req.headers['content-length'], 10)
        : null;

    // self-awareness
    if (req._limit) return next();
    req._limit = true;

    // limit by content-length
    if (len && len > bytes) {
      var ret = {a:'bbbbb',b:'b'};  
      res.writeHead(413);
      res.write(JSON.stringify(ret));
      res.end();

      return next(utils.error(413));
    }

    // limit
    req.on('data', function(chunk){
      received += chunk.length;
      if (received > bytes) req.destroy();
    });

    next();
  };
};
4

1 回答 1

1

这里发生的是第一个“如果”:

// limit by content-length
if (len && len > bytes) {
  var ret = {a:'bbbbb',b:'b'};  
  res.writeHead(413);
  res.write(JSON.stringify(ret));
  res.end();

  return next(utils.error(413));
}

仅当浏览器发送 'content-length' 标头时才会执行,但情况并非总是如此。大多数情况下,它会回退到在这里即时计算字节数:

// limit
req.on('data', function(chunk){
  received += chunk.length;
  if (received > bytes) req.destroy();
});

但是正如您所看到的,当它超过允许的限制时,它只会破坏请求,从而导致来自浏览器的重置消息。你可以把它改成这样:

// limit
req.on('data', function(chunk){
  received += chunk.length;
  if (received > bytes) {
    var ret = {a:'bbbbb',b:'b'};  
    res.writeHead(413);
    res.write(JSON.stringify(ret));
    res.end();
  }
});

它似乎有效,但我不确定这是否是正确的方法。

于 2012-07-23T21:54:18.313 回答