简体   繁体   中英

nodejs express Error: Can't set headers after they are sent

I am reading a growing file in nodejs. Using below code in my app.js.

app.post('/readfile',function (req,res) {   
    var fullfilename = req.body.filepath+"\\"+req.body.filename;
    var bite_size = 256;
    var readbytes = 0;
    var file;

    fs.open(fullfilename, 'r', function(err, fd) {
        file = fd;      
        if(err){console.log(err); throw err; return;};
        var mybuff;
        var func = (function readsome() {               
        var stats = fs.fstatSync(fd); // yes sometimes async does not make sense!
                if(stats.size<readbytes+1) {                    
                    setTimeout(readsome, 1000);
                }
                else {
                    fs.read(fd, new Buffer(bite_size), 0, bite_size, readbytes, function (err, bytecount, buff) {
                    //console.log(buff.toString('utf-8', 0, bytecount));
                    res.json(buff.toString('utf-8', 0, bytecount));
                    readbytes+=bytecount;
                    process.nextTick(readsome);
                    });
                };          
        })();           
    }); 
}); 

And calling this in html like below ,

var myApp= angular.module("myApp", [])
myApp.controller('Ctrl1', function ($scope, $http,$q) {
        var FileName = "test.txt"
        var obj = {"filepath" : 'D:\\Temp', "filename" : FileName};

        $http({
                url: '/readTfile',
                method: "POST",
                data: JSON.stringify(obj)
                //timeout: canceller.promise,
                //headers: {'Content-Type': 'application/json','charset' : 'utf-8'}
                }).success(function(result) {               
                $scope.myfiledata = result;                     
                }).error(function(data, status) {
                console.log(data);
                }); 
});

This is working fine when i put this app.js code in a separate file (readfile.js) but when i put in app.js it gives error.

_http_outgoing.js:357
    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:357:11)
    at ServerResponse.header (D:\myapp\node_modules\express\lib\response.js:725:10)
    at ServerResponse.send (D:\myapp\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (D:\myapp\node_modules\express\lib\response.js:256:15)
    at D:\myapp\app.js:130:10
    at FSReqWrap.wrapper [as oncomplete] (fs.js:682:17)
[nodemon] app crashed - waiting for file changes before starting...

Please help to find where is the mistake and what to be changed. Secondly i want to stop this call on button click, how can i do that ?

This is just a guess, but, did you remove the old code, before adding the code in app.js ?

Maybe your /readfile route is added by both app.js and in the separate file, so that first route sends out the response, and when the second route starts to do the same, it gets the error of response already been sent.

You can only call res.json once on a request. It sets the relevant headers, JSON encodes the data, sends it as the response and then ends the request.

If you just want to write some of the data you can use write : https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback

Or maybe you could using piping to do it all for you instead?

var readStream = fs.createReadStream(fullfilename);
readStream.pipe(res);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM