-1

I'm new to Connect.js and I am trying to figure out how exactly it is working. I wrote a very simple function - reading a file and printing it. I am not sure why I am getting this error Error: Can't set headers after they are sent. Any help will be much appreciated!

I have studies this question Nodejs: Connect and “writeHead” in first connect-callback. It was very helpful, but it still did not solve the problem how to pass the data that I am reading from the file.

Here is the code:

var connect = require('connect'),
    path = require('path'),
    url = require('url'),
    fs = require('fs');

const hostname = '127.0.0.1';
const port = 3030;

var interceptorFunction = function (req, res, next) {
    fs.readFile(__dirname + "/docs/test.html", 'utf-8', function (error, data) {
        if (error) {
            res.writeHead(500);
            return res.end('Error');
        }
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.write(data);
            return res.end('Success');

    });

    next();
}

var server = connect()
        .use(interceptorFunction);

server.listen(port, hostname, function () {
    console.log('Server running at http://' + hostname + ':' + port + '/');
});

Thanks to the answer below and the Nodejs: Connect and “writeHead” in first connect-callback, I managed to produce a working code. One of the problem that I had regarding Connect.js was about the usage of next(). Since the application is very simple, I was using next, without having a callback after it, thus the program crashed.

Here it is the working code. I hope it might be useful for someone else:

var connect = require('connect');
var fs = require('fs');

var simpleApp = connect();

simpleApp
    .use(function (req, res, next) {

        fs.readFile(__dirname + "/docs/test.html", 'utf-8', function (error, data) {
            if (error) {
                res.statusCode = 500;
                return res.end();
            }

            res.statusCode = 200;
            res.setHeader('Content-Type', 'text/html');
            return res.end(data);

        });

        console.log('Pre');
        next();
        console.log('Post');
    })
    .use(function (req, res) {
        console.log('Some other functionality here');
    });

simpleApp.listen(3030);
Community
  • 1
  • 1
Neli Chakarova
  • 660
  • 1
  • 5
  • 18
  • 4
    Possible duplicate of [Nodejs: Connect and "writeHead" in first connect-callback](http://stackoverflow.com/questions/19980426/nodejs-connect-and-writehead-in-first-connect-callback) – Dan Sep 20 '16 at 12:52
  • `writeHead` writes headers immediately. You can't use `writeHead` in conjunction with other methods that write to the response. See the question I've marked this as a duplicate as. – Dan Sep 20 '16 at 12:53
  • This means then that I have to pass the data parameter to last callback and set it there? Is that right? – Neli Chakarova Sep 20 '16 at 13:13

1 Answers1

0

Instead of:

res.writeHead(500);
return res.end('Error');

you can try this for Express 4.x:

res.status(500);
res.send('Error');
return res.end();

or this for Express 3.x:

res.send(500, 'Error');
return res.end();

or this for Connect without Express:

res.statusCode = 500;
return res.end('Error');

And instead of:

res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
return res.end('Success');

you can try for Express 4.x:

res.status(200);
res.type('html');
res.send(data);
return res.end();

or this for Express 3.x:

res.set('Content-Type', 'text/html');
res.send(200, data);
return res.end();

or this for Connect without Express:

res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
return res.end(data);

etc. It can be written using some shortcuts but here I wrote everything explicitly to show what's going on.

Note that when you are already writing your data then there's no need to add the 'Success' string at the end.

My suggestion is that if you're new to Connect anyway and you have problems with writing your code then maybe you could try Express. It's much more convenient to use and has much better documentation - see:

For more info on serving static files n Node, see this answer.

rsp
  • 107,747
  • 29
  • 201
  • 177
  • For some reason I get TypeError: res.status is not a function – Neli Chakarova Sep 20 '16 at 13:17
  • @NeliChakarova What version of Express are you using? – rsp Sep 20 '16 at 13:17
  • @NeliChakarova See my updated answer for examples for Express 3.x – rsp Sep 20 '16 at 13:20
  • I am using only Connect.js – Neli Chakarova Sep 20 '16 at 13:21
  • @NeliChakarova Ok. I added examples for Connect without Express. Does it work for you? – rsp Sep 20 '16 at 13:42
  • I think I am doing something really wrong. What I have now is var interceptorFunction = function (req, res, next) { fs.readFile(__dirname + "/docs/test.html", 'utf-8', function (error, data) { if (error) { res.statusCode = 500; return res.end(); } res.statusCode = 200; res.setHeader('Content-Type', 'text/html'); return res.end(data); }); next(); } And it still crashing :/ – Neli Chakarova Sep 20 '16 at 13:48
  • @NeliChakarova If you can't write a working code using Connect then why won't you try Express? It's much simpler. For serving static files as you are trying to do here I wrote an example on github: https://github.com/rsp/node-express-static-example - the entire code for serving files is [two lines](https://github.com/rsp/node-express-static-example/blob/master/app.js#L5-L7). – rsp Sep 20 '16 at 13:53
  • I know, I have already done it with express and I will never use anything else! I am trying to take it step by step and go throught Node, Connect and Express, but I just don't get Connect and it drives me crazy. Thank you very much for the help!!! – Neli Chakarova Sep 20 '16 at 13:57
  • Finally! Your solution was right, I had to either remove the next() or keep the last callback. – Neli Chakarova Sep 20 '16 at 14:19