Node JSON output malforms, unable to set HTTP Header: Content-Length to fix

express, http, javascript, node.js, sails.js

Solution

I suspect your data event is firing multiple times (because that's how it works, multiple `data` events and then one final `end` event.)

You might want to read through the readable stream documentation (that's what the `response` object is) http://nodejs.org/api/stream.html#stream_class_stream_readable

I'd try changing your handler to look something like:

res.writeHead(200, {
  'Content-Type': 'application/json',
  'Content-Length': Buffer.byteLength(json, 'utf8')
});

response.on('data', function(json){
  res.write(json, 'UTF-8');
});
response.on('end', function(){
  res.end();
});

Although you might be able to just pipe it through:

response.pipe(res);

(Instead of explicitly listening to the data and end events)

Problem

The problem Context & intent I'm using a Node backend to (1) request API data from the Feedly Cloud, (2) output that data in JSON format and then (3) retrieve it from within a JS frontend. This question relates to phase (2) only. Initial issue Whilst trying to print the data for the front-end to retrieve, I noticed that Node cut off mid-stream, leaving malformed JSON. Attempted solution I tried setting response headers for Content-Length before writing the content of the response, to force it to print the whole thing. That worked, around twice. But then it started fussing: Ongoing failure Now the app crashes on function run, claiming that I'm setting HTTP headers AFTER writing the content, or outputting to page, when as far as I'm aware I am not. The code ``` var http = require('http') , authCode = 'xyz'; var FeedlyController = { api: function(req, res) { http.get({ host : "cloud.feedly.com", path : "/v3/"+req.params.resource, headers: { Authorization: "OAuth "+authCode } }, function(response) { response.on('data', function(json){ res.writeHead(200, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(json, 'utf8') }); res.write(json, 'UTF-8'); res.end(); }); }); } } module.exports = FeedlyController; ``` The error ``` _http_outgoing.js:331 throw new Error('Can\'t set headers after they are sent.'); ^ Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:331:11) at ServerResponse.res.setHeader (/Users/jan/Sites/proxenos/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:63:22) at ServerResponse.<anonymous> (/Users/jan/Sites/proxenos/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:80:14) at Array.forEach (native) at ServerResponse.res.writeHead (/Users/jan/Sites/proxenos/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:79:28) at IncomingMessage.<anonymous> (/Users/jan/Sites/proxenos/api/controllers/FeedlyController.js:12:19) at IncomingMessage.EventEmitter.emit (events.js:107:17) at readableAddChunk (_stream_readable.js:159:16) at IncomingMessage.Readable.push (_stream_readable.js:126:10) at HTTPParser.parserOnBody (_http_common.js:132:22) ```

Original source