Search code examples
node.jsconnect.js

Error: Can't set headers after they are sent. Connect.js


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);

Solution

  • 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.