2013-06-21 79 views
5

如果快遞bodyParser未啓動,如何才能訪問POST請求中的數據?如何通過假設默認內容類型解析Express/NodeJs中缺少內容類型的HTTP請求?

var server = express(); 
server.use(express.bodyParser()); 
server.post('/api/v1', function(req, resp) { 
    var body = req.body; 
    //if request header does not contain 'Content-Type: application/json' 
    //express bodyParser does not parse the body body is undefined 
    var out = { 
    'echo': body 
    }; 
    resp.contentType('application/json'); 
    resp.send(200, JSON.stringify(out)); 
}); 

注:ExpressJs 3.X + req.body無法自動獲得,並要求bodyParser激活。

如果未設置內容類型標題,是否可以指定缺省內容類型application/json並觸發bodyParser

否則是否可以從這個快速POST函數內使用裸nodejs方式訪問POST數據?

(如req.on('data', function...

+2

只使用'req.on('data')'或做'req.headers ['content-type'] = req.headers ['content-type'] || 'application/json'在主體解析器之前,但實際上這是客戶端錯誤。 –

+0

@JonathanOng謝謝。是的,我知道這是一個客戶端錯誤 - 只是試圖解決它。在身體解析器開始之前,我該如何去做一些事情? AFAICT,這個快速PUT回調函數被輸入時,它已經被觸發。 – bguiz

回答

12

你有一堆選項,包括手動調用快車(連接,真的)自己的中間件功能(說真的,去閱讀源代碼。他們只是功能並沒有魔淵混淆你)。所以:

function defaultContentTypeMiddleware (req, res, next) { 
    req.headers['content-type'] = req.headers['content-type'] || 'application/json'; 
    next(); 
} 

app.use(defaultContentTypeMiddleware); 
app.use(express.bodyParser()); 
+0

感謝您的答案 - 只是檢查,因爲我們直接使用內容類型作爲散列,是否大寫會影響這個?即'req.headers ['content-type']'vs'req.headers ['Content-Type']'? – bguiz

+0

他們爲你小封裝。 http://nodejs.org/docs/latest/api/all.html#all_message_headers –

+0

@ Peter Lyons不幸的是,以這種方式設置標題屬性似乎對'bodyParser'沒有任何影響。感謝給我寫自己的中間件的想法 - 不知道爲什麼我自己不這樣做 - 但最終我最終做的是編寫自己的中間件,它本質上是一個最小包裝圍繞'req.on('data',function ...'和'JSON.parse'。+1並向您查詢! – bguiz

3

我使用這個中間件,bodyParser踢之前,這可能有所幫助。 它偷看請求流的第一個字節,並進行猜測。 這個特殊的應用程序只處理XML或JSON文本流。

app.use((req,res, next)=>{ 
    if (!/^POST|PUT$/.test(req.method) || req.headers['content-type']){ 
     return next(); 
    } 
    if ((!req.headers['content-length'] || req.headers['content-length'] === '0') 
      && !req.headers['transfer-encoding']){ 
     return next(); 
    } 
    req.on('readable',()=>{ 
     //pull one byte off the request stream 
     var ck = req.read(1); 
     var s = ck.toString('ascii'); 
     //check it 
     if (s === '{' || s==='['){req.headers['content-type'] = 'application/json';} 
     if (s === '<'){req.headers['content-type'] = 'application/xml'; } 
     //put it back at the start of the request stream for subsequent parse 
     req.unshift(ck); 
     next(); 
    }); 
});