2017-06-15 6 views
1

Parsen Ich bin von einem Remote-Server für die Handhabung, entlang der folgenden Zeilen eine Anfrage an Rohr versucht:Knoten express/Anfrage: kochend eine POST-Anforderung mit dem Körper

var destination = request(url); 
req.pipe(destination).pipe(res); 

Der für GET Anfragen ganz gut funktioniert. Aber für POST Anfragen ich kämpfe. Ein wichtiger Punkt ist zu beachten, glaube ich, ist, dass für POST Anfragen ich einen Körper-Parser vor meiner POST Route Handler bin mit, um den Körper von der POST Anfrage zu extrahieren ... es ist nur ein einfacher Textkörper-Parser, weil der Körper enthält Klartext:

var postRouteHandler = someFunction; 
var bodyParser = require('body-parser'); 
var textParser = bodyParser.text({ 
    limit: '50kb' 
}); 
app.use('/postRoute', [textParser, postRouteHandler]); 

Von this issue und this issue scheint es mir, dass auf der POST Anfrage, bevor Sie Rohr jede Verarbeitung zu tun wird es ein Problem verursachen. Tatsächlich, wenn ich den Parser entferne, scheint die Rohrleitung in Ordnung zu sein.

Das Problem ist, dass ich zuerst den Körper zu untersuchen, einige anfängliche Verarbeitung zu tun und dann, ob oder nicht Rohr auf den Remote-Server an alle, die Anforderung zu bestimmen. So brauche ich , um den Körper vor der Verrohrung zu analysieren.

Gibt es eine Möglichkeit, dieses Problem zu umgehen?

Antwort

6

Das Problem ist, dass mit den Strömen (wie req), wenn Sie es gelesen haben Sie es nicht zurücksetzen.

Da body-parser den Stream bereits gelesen hat, wird es nicht funktionieren, weil das versuchen wird, den Stream erneut zu lesen (der an diesem Punkt bereits erschöpft ist).

Eine Abhilfe würde den Text von body-parser, lesen Sie nehmen sein und einen minimalen req „Klon“, um für request schaffen zu können, entlang der Anfrage weitergeben müssen:

var intoStream = require('into-stream'); 
var bodyParser = require('body-parser'); 
var textParser = bodyParser.text({ limit: '50kb' }); 

var postRouteHandler = function(req, res) { 
    let text = req.body; 
    if (! shouldPipe(text)) { 
    return res.sendStatus(400); // or whatever 
    } 

    // Here's where the magic happens: create a new stream from `text`, 
    // and copy the properties from `req` that `request` needs to pass 
    // along the request to the destination. 
    let stream  = intoStream(text); 
    stream.method = req.method; 
    stream.headers = req.headers; 

    // Pipe the newly created stream to request. 
    stream.pipe(request(url)).pipe(res); 
}; 
app.use('/postRoute', [textParser, postRouteHandler]); 
+0

Lernen vom Meister! Genius! Nicht nur eine großartige Lösung, sondern auch eine klare und prägnante Erklärung, warum das Problem auftritt. Du bist in der Tat der Meister @robertklep! – drmrbrewer

+0

... nur eine Sache ... sollte es 'request.post (url)' anstatt nur 'request (url)' sein? – drmrbrewer

+0

Ich bin mir ziemlich sicher, dass 'request'' req.method/stream.method' verwendet, um zu bestimmen, welche Art von Anfrage auszuführen ist, so dass Sie nicht explizit darüber sein müssen. – robertklep

1

Sie sollten Ihre eigene Middleware erstellen, wenn der Parser das Problem verursacht. In aller Ehrlichkeit möchten Sie vielleicht den Körper anders analysieren als den Körper-Parser.

das begrenzte Wissen über das, was der Rest Ihres Projekts Sie Middleware erstellen könnte tut Angesichts der Körper Parser Middleware einzuhaken und nur einen Klon der Anfrage senden. Dies ist jedoch nicht sehr effizient, wird aber funktionieren und kann Ihnen helfen, in die richtige Richtung zu weisen.

var postRouteHandler = someFunction; 
var bodyParser = require('body-parser'); 
var textParseMiddleware = function (req, res, next) { 

    var requestclone = _.clone(req); 
    var textParser = bodyParser.text({ 
    limit: '50kb' 
    }); 

    textParser(requestclone, res, function(){ 
    console.log('examine the body here', requestclone.body); 
    }); 


} 

app.use('/postRoute', [textParserMiddleWare, postRouteHandler]); 

Ich habe den obigen Code nicht getestet.

0

Brauchen Sie noch einen riesen Daten senden per POST bekam ich Fehler: Socket auflegen/Code: 'ECONNRESET'. Wurde in der Lage, es über steigende Grenze im Body-Parser aufzulösen.

var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json({limit:'50mb'}));

Verwandte Themen