重定向请求时生成 ERR_HTTP_HEADERS_SENT 错误

Posted

技术标签:

【中文标题】重定向请求时生成 ERR_HTTP_HEADERS_SENT 错误【英文标题】:ERR_HTTP_HEADERS_SENT Error Generated When Redirecting Requests 【发布时间】:2019-04-03 22:20:27 【问题描述】:

我正在使用 Node.js 框架和 Express 模块编写一个 API 包装器,将请求重定向到另一个服务器。我可以成功地将请求重定向到目标服务器,并且收到包含 JSON 有效负载的有效响应。但是,在初始请求之后,如果我尝试另一个请求,我会收到以下错误。

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

这是我为 HTTP GET Express 路由编写的代码示例:

app.get('/companyrecords/:name', function(req, res) 

  const options = 
    protocol: 'http:',
    hostname: 'myhost',
    port: 5001,
    method: 'GET',
    path: '/path/to/resource/?name=name',
    auth: 'username:password',
    headers: 
      Connection: 'close'
    
  

  const myAppReq = http.request(options, (myAppRes) =>
    console.log(`STATUS: $myAppRes.statusCode`);
    myAppRes.on('data', (chunk) => 
      console.log(`BODY: $chunk`);
      res.send(chunk);
    );
        myAppRes.on('end', () => 
        res.end('No more data to send.');
    );
  );

  myAppReq.on('error', (err) => 
    console.error(`Problem with request: $err.message`);
  );

  myAppReq.write('');
  myAppReq.end();
);

不知道为什么我会收到此错误,因为我正在调用 req.write() 方法以便发送请求的标头。查看错误堆栈跟踪时,当我在“数据”事件的回调中调用 res.send() 方法时,会出现错误。也许我不了解请求之间的执行流程或发出事件的顺序。任何指导/信息将不胜感激。

【问题讨论】:

【参考方案1】:

您不应该在data 事件回调中发送响应,因为当您收到第一块数据时会发送响应。您应该做的是将chunk 写入响应流并在end 事件回调中发送响应:

const myAppReq = http.request(options, (myAppRes) =>
    myAppRes.on('data', (chunk) => 
      res.write(chunk);
    );
    myAppRes.on('end', () => 
      res.end();
    );
);

【讨论】:

好的,我想我现在明白了。我发现 Express 中的 res 对象“只是 Node 自身响应对象的增强版”[链接]expressjs.com/en/4x/api.html#res。我使用 res.send() 因为我不知道它有一个 write 方法。我注意到 Express 对象从 Node 自己的 HTTP 模块继承了它们的大部分属性和方法。我不理解的一件事是请求和响应对象发出的事件序列如何确定何时将数据写入响应流。无论如何,我将代码更改为您建议的代码,并且效果很好。谢谢!

以上是关于重定向请求时生成 ERR_HTTP_HEADERS_SENT 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 CloudFront 函数重定向请求时包含 HTTP 请求正文?

JSP如何实现网页重定向

laravel 4.2在重定向时重新生成会话

Zip 下载后重定向或刷新页面

python 爬网页 遇到重定向怎么处理

与改造一起使用时,OkHttp 不会重定向 POST 请求