简体   繁体   English

设置内容类型后发送后无法设置标题

[英]Can't set headers after they are sent after setting the content-type

I am trying to get an object from my server API. 我正在尝试从服务器API获取对象。

This API has it as a stream. 此API将其作为流。

I can get its mime thanks to its key (which ends by .jpg etc...). 由于其键(以.jpg等结尾),我可以得到它的mime。 I would like to send back a content-type with the right type-mime and not always with application/octet-stream . 我想发回带有正确的type-mime的content-type,而不总是发送给application/octet-stream

I found in npm mime which does the work but when I go to the url http://localhost:3000/file/myb/userId/test.jpeg the server shutdown and throw : 我在npm mime中发现它可以工作,但是当我转到URL http://localhost:3000/file/myb/userId/test.jpeg ,服务器关闭并抛出:

http.js:691
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.js:691:11)
at ServerResponse.res.setHeader (D:\Utilisateurs\A579871\Documents\GIT\shb-  gitrepository-1\node_modules\express\node_modules\connect\lib\patch.js:63:22)
at ServerResponse.<anonymous> (D:\Utilisateurs\A579871\Documents\GIT\shb-gitrepository-1\node_modules\express\node_modules\connect\lib\patch.js:80:14)
at Array.forEach (native)
at ServerResponse.res.writeHead (D:\Utilisateurs\A579871\Documents\GIT\shb-gitrepository-1\node_modules\express\node_modules\connect\lib\patch.js:79:28)
at IncomingMessage.<anonymous> (D:\Utilisateurs\A579871\Documents\GIT\shb-gitrepository-1\server.js:49:17)
at IncomingMessage.EventEmitter.emit (events.js:95:17)
at IncomingMessage.<anonymous> (_stream_readable.js:746:14)
at IncomingMessage.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)

I found this topic about the subject and tried to use the advices without finding the solution 我找到了与此主题相关的主题,并尝试使用建议而未找到解决方案

Error: Can't set headers after they are sent to the client 错误:将标头发送到客户端后无法设置标头

Here is my code : 这是我的代码:

var express = require('express');
var http = require('http');
var mime = require('mime');
var app = express();
var maxAge = 31557600000;
var port = 3000;

app.use(express.static(__dirname + '/app'));

app.get('/file/:bId/:userId/:fileKey', function(req, res) {

    var headersGet = {
        'auth-format': 'UID',
        'Authorization': req.params.userId
    };

    var optionsGet = {
        host: 'localhost',
        port: 5000,
        path: '/' + req.params.bId + '/' + req.params.fileKey,
        method: 'GET',
        headers: headersGet
    };

    var reqGet = http.request(optionsGet, function(resGet) {
        resGet.on('data', function(d) {
            type = mime.lookup(req.params.fileKey);
            var charset = mime.charsets.lookup(type);
            var newHead = {};

            if (charset) {
                newHead = {
                    "Content-Type": type
                };
            } else {
                newHead = {
                    "Content-Type": type,
                    "charset": charset
                };
            }

            res.writeContinue();
            res.writeHead(200, newHead);
            res.write(d);
            res.end(d);
        });
    });

    reqGet.end();
    reqGet.on('error', function(e) {
        console.error(e);
    });

});

app.listen(port);

console.log('Listening on port ' + port);

The major problem here is that you must not assume you will always get a single 'data' event. 这里的主要问题是,您不能假设您将始终获得单个“数据”事件。 Instead, write the header once (use a boolean guard variable if you want to do this in a 'data' event so that it only gets done once), write the data, and on resGet 's 'end' event, end the response. 相反,只需编写一次标头(如果要在“数据”事件中执行此操作,则使用布尔型保护变量,以便仅完成一次),然后写入数据,并在resGet的“ end”事件中结束响应。

OR: write the header (outside of the 'data' event) and just resGet.pipe(res); 或:编写标头(在“数据”事件之外),然后再resGet.pipe(res); , removing the resGet 's 'data' and 'end' event handlers entirely. ,完全删除resGet的'data'和'end'事件处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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