2013-07-12 7 views
5

Ich bin Prototyping eine App mit der nativen Mongo Rest API, wo Knoten etwa 400K von JSON zurückgibt. Ich benutze den folgenden er einen Antrag auf Mongo nativen api maket und das Ergebnis zurück:NodeJS/ExpressJS senden Antwort von großen Datenmengen in 1 Stream

http.request(options, function(req) 
    { 
    req.on('data', function(data) 
     { 
console.log(data,data.rows); 
     response.send(200, data); 
     } 
    ); 
    } 
) 
.on('error', function(error) 
    { 
console.log('error\t',error); 
    response.send(500, error); 
    } 
) 
.end(); 

Wenn ich http://localhost:8001/api/testdata über curl getroffen, die Antwort richtig ist (beide, was zu Knoten der Konsole aus den console.log ausgegeben wird und was empfangen werden durch Locken). Aber wenn ich es über Ajax in meiner App traf, ist der Stream ... unterbrochen, sogar data ausgegeben an Nodes Konsole (Terminal) ist ungerade: Es hat mehrere EOFs, und die Netzwerk> Antwort für den Aufruf in Chrome Dev Tools endet am ersten EOF.

Eine andere seltsame Sache: data wie folgt aussieht:

{ 
    "offset": 0, 
    "rows": [ … ] 
} 

aber in keinem der beiden Knoten noch clientseitige (Winkel-) kann ich Referenz data.rows (es gibt nicht definiert). typeof data gibt [object Object] zurück.

EDIT Die Anforderungs-Header für beide curl und eckig (wie durch Knoten gemeldet) sind:

req.headers: { 
    'x-action': '', 
    'x-ns': 'test.headends', 
    'content-type': 'text/plain;charset=utf-8', 
    connection: 'close', 
    'content-length': '419585' 
} 

EDIT geprüft I-Antwort-Header in beiden Winkel und kräuseln direkt (anstatt von Node), annnd es gibt eine Nichtübereinstimmung (die gleiche Ausgabe von sowohl curl und Winkel direkt anstelle von node):

access-control-allow-headers: "Origin, X-Requested-With, Content-Type, Accept" 
access-control-allow-methods: "OPTIONS,GET,POST,PUT,DELETE" 
access-control-allow-origin: "*" 
connection: "keep-alive" 
content-length: "65401" // <---------------- too small! 
content-type: "application/octet-stream" 
//    ^-- if i force "application/json" 
// with response.json() instead of response.send() in Node, 
// the client displays octets (and it takes 8s instead of 0s) 
date: "Mon, 15 Jul 2013 18:36:50 GMT" 
etag: ""-207110537"" 
x-powered-by: "Express" 
+1

Ich würde versuchen, die Header und Körper in Node zu lesen und es verfolgen/drucken, was in beiden Fällen durchkommt. Versuchen Sie zu verstehen, was das Diff der Anforderungsinformationen oder die Art der Anforderungen ist, dann suchen Sie nach bestimmten Antworten zu Möglichkeiten, die Unterschiede zwischen Ihrer Anforderung und der Ajax-Anforderung zu lösen (Header in Winkel usw. festlegen) – shaunhusain

+0

@ Shaunhusain, ich überprüfte die Header, und sie sind die gleichen, also habe ich auch das gesamte 'req' Objekt (mit FileMerge) überprüft und es gibt 0 Unterschiede _ – jacob

+1

gut das ist gruselig :) Entschuldigung, ich weiß nicht, was ich dir sagen soll Wenn die an eine Maschine gesendeten Daten genau gleich sind und auf zwei verschiedene Arten reagieren, habe ich keine Ahnung, was passiert. Vielleicht haben wir die Knotengötter oder die Winkelgötter (vielleicht einen untergeordneten OSI-Gott) verärgert und wir sollten umkehren. Wie erfassen Sie Ihre Daten? Ich habe Charles mit viel Erfolg in der Vergangenheit benutzt (Bist du sicher, dass das passiert?) – shaunhusain

Antwort

10

Knotens http.request() gibt Daten in chunks zum Streamen (wäre schön, wenn sie dies explizit angeben). Daher ist es notwendig, jeden Block in den Hauptteil der Antwort von Express zu schreiben, listen for the end of the http request (was nicht wirklich dokumentiert ist), und dann response.end() aufzurufen, um die Antwort tatsächlich zu beenden.

var req = http.request(options, function(res) 
    { 
    res.on('data', function(chunk) { response.write(chunk); }); 
    res.on('end', function() { response.end(); }); 
    } 
); 
req.on('error', function(error) { … }); 
req.end(); 

Wo response ist Express Antwort die die ursprünglichen Client-Anforderung (curl oder Ajax-Aufruf des Winkels).

+1

Ich denke, dies rettete gerade mein Leben zusammen mit [AngularUI typeahead Konflikt mit $ Ressource] (http://stackoverflow.com/questions/15930339/how-to-tie-angular-uis-typeahead -mit-einem-server-via-http-fuer-serverseitig-optimi) –

+1

Sie können pipe() für eine optimierte Implementierung verwenden. Es gibt ein winziges NPM-Paket, das das Boilerplating übernimmt (ich glaube, es heißt Request). – jacob

+0

@jacod Any Npm Link dafür, das ist, was ich auf [npmjs] (https://www.npmjs.com/package/pipe) –

Verwandte Themen