【问题标题】:nodejs express Error: Can't set headers after they are sentnodejs express错误:发送后无法设置标头
【发布时间】:2017-09-11 23:33:55
【问题描述】:

我正在 nodejs 中读取一个不断增长的文件。在我的 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);
                    });
                };          
        })();           
    }); 
}); 

并像下面这样在 html 中调用它,

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

当我将此 app.js 代码放在单独的文件 (readfile.js) 中时,这工作正常,但是当我放入 app.js 时,它会出错。

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

请帮助找出错误在哪里以及要更改的内容。其次,我想在单击按钮时停止此调用,我该怎么做?

【问题讨论】:

标签: javascript node.js express


【解决方案1】:

这只是一个猜测,但是,在 app.js 中添加代码之前,您是否删除了旧代码?

也许你的 /readfile 路由是由 app.js 和单独的文件添加的,所以第一个路由发出响应,当第二个路由开始做同样的事情时,它得到响应已经发送的错误.

【讨论】:

  • 是的。当我用不同的 js 测试时,它不存在 app.js。代码一次只在一个地方。
【解决方案2】:

您只能根据请求致电res.json 一次。它设置相关的标头,JSON 对数据进行编码,将其作为响应发送,然后结束请求。

如果你只是想写一些数据你可以使用write:https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback

或者也许您可以使用管道来代替您完成这一切?

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

【讨论】:

  • 谢谢@skirtle。首先,我使用“createReadStream”创建了与静态文件配合良好的 api,但我也想捕获添加的新行。我为此使用了 fs.watch 和 fs.read ,这样我就可以在需要块中的数据时放置偏移量。是否可以对 createReadStream 做同样的事情?任何工作示例都会有很大帮助。
猜你喜欢
  • 2017-03-03
  • 1970-01-01
  • 2017-12-22
  • 2018-09-02
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
相关资源
最近更新 更多