1

ブラウザからnodejsとexpressへの「POST」値を取得しています。
ファイルを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'));
});

ポストファイルを受信できます。
ただし、ファイル サイズの制限を 50 MB に設定しました。
50MBを超えるファイルサイズを投稿するとき。
ブラウザは、完了するまでファイルのアップロードを続けます。
私が必要とするのは、サイズが50MBを超える場合です。413 (要求エンティティが大きすぎます。つまり、エラーが出力されます) の HTTP コードがブラウザに返され、アップロードが停止されます。

エクスプレスソースコードを調査しました。 45 行目の node_modules/express/node_modules/connect/lib/middleware/limit.js にある connect
を使用し ます。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

ここで何が起こるかというと、最初の「if」:

// 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 に答える