2013-04-03 40 views
3

我想建立一個服務器,可以接受與快遞gzip的POST數據。我想我可以編寫自己的中間件來將請求流傳遞給zlib.createGunzip()流。問題是,如何實現這一點,之後,express.bodyParser()中間件仍然能夠解析我的gunzipped POST數據?我如何快速POST gun POST POST請求數據?

我試圖取代用於zlib流的那些原始的請求流的方法,但只是取得了bodyParser返回一個「錯誤的請求」錯誤:

var express = require('express'); 
var app = express(); 

function gUnzip(req, res, next) { 
    var newReq; 
    if (req.headers['content-encoding'] === 'gzip') { 
    console.log("received gzipped body"); 
    newReq = req.pipe(zlib.createGunzip()); 
    Object.getOwnPropertyNames(newReq).forEach(function (p) { 
     req[p] = newReq[p]; 
    }); 
    } 
    next(); 
} 

app.use(gUnzip); 
app.use(express.bodyParser()); 

app.listen(8080); 

有沒有一種方法,使這項工作而不用在我自己的中間件中重寫bodyParser()中間件?編輯: 這是同一個問題:Unzip POST body with node + express。但在答案中,他只是在自己的中間件中做了什麼,express.bodyParser()應該做什麼,這是我想要避免的。我正在尋找一種方法來簡單地從流中解壓縮請求數據,然後將它傳遞給bodyParser(),bodyParser()需要一個流本身,如http://www.senchalabs.org/connect/json.html所示。

+0

如果'刪除req.headers [「內容編碼」]',你不會得到一個壞'再Request',但它仍然沒有按」 t工作:( – robertklep

+0

據我所見,你不能'覆蓋'這樣的請求對象,我想你需要自己實現'bodyParser'功能:( – robertklep

回答

-2

您是否嘗試過使用內置的compress中間件。它記錄在expressjsreference documentation

app.use(express.compress()); 

也許你可以在這裏找到,而不是一些有用的東西:Unzip POST body with node + express

+0

是的,但是express.compress( )只支持gzipping服務器_responses_。我想從客戶端發送一個gzip的POST _request_並將其解壓到服務器上。 –

+0

Aha。我錯過了這個部分,對於這個問題很抱歉 – NilsH

+0

也許同樣的問題:http:// stackoverflow .com/questions/14194864/unzip-post-body-with-node-express – NilsH

1

壓縮請求主體,一般不使用,因爲你無法協商客戶機之間的內容編碼和服務器很容易(還有另一個關於我相信的stackoverflow問題)。大多數服務器不支持壓縮的請求體,並且您真正需要的唯一時間是針對客戶端發送大型主體的API。

body-parser,特別是raw-body,不支持它,因爲用例很小,儘管我已經加入了它。現在,你將不得不創建你的body-parser。幸運的是,這很容易,因爲您可以僅分叉body-parser並利用raw-body。主代碼,你會增加約https://github.com/expressjs/body-parser/blob/master/index.js#L80

var zlib = require('zlib') 

     var stream 
     switch (req.headers['content-encoding'] || 'identity') { 
      case 'gzip': 
       stream = req.pipe(zlib.createGunzip()) 
       break 
      case 'deflate': 
       stream = req.pipe(zlib.createInflate()) 
       break 
      case 'identity': 
       break 
      default: 
       var err = new Error('encoding not supported') 
       err.status = 415 
       next(err) 
       return 
     } 

     getBody(stream || req, { 
      limit: '1mb', 
      // only check content-length if body is not encoded 
      length: !stream && req.headers['content-length'], 
      encoding: 'utf8' 
     }, function (err, buf) { 

     })