我收到“错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头”

Posted

技术标签:

【中文标题】我收到“错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头”【英文标题】:I received "Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client" 【发布时间】:2020-11-01 01:51:36 【问题描述】:

我第一次使用 Node.js 和 Express 来制作 API,但遇到了一些问题。 我正在使用 Node.JS 13.11.0 和 Express 4.17.1。 当我尝试访问 127.0.0.1:4008/api/nbhbdm 并附加参数时,收到此错误。

_http_outgoing.js:535
    throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:535:11)
    at ServerResponse.header (/Users/zihangu/Desktop/TZG API/nbhbdm/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/zihangu/Desktop/TZG API/nbhbdm/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/zihangu/Desktop/TZG API/nbhbdm/node_modules/express/lib/response.js:267:15)
    at exports.XMLHttpRequest.httpRequest.onreadystatechange (/Users/zihangu/Desktop/TZG API/nbhbdm/app.js:28:17)
    at exports.XMLHttpRequest.dispatchEvent (/Users/zihangu/Desktop/TZG API/nbhbdm/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25)
    at setState (/Users/zihangu/Desktop/TZG API/nbhbdm/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14)
    at IncomingMessage.<anonymous> (/Users/zihangu/Desktop/TZG API/nbhbdm/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:440:13)
    at IncomingMessage.emit (events.js:315:20)
    at IncomingMessage.Readable.read (_stream_readable.js:508:10) 
  code: 'ERR_HTTP_HEADERS_SENT'

Process exited with code 1

以下是我的代码。

const express = require('express');
const app = express();

app.all('*', function(req, res, next) 
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",'3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
  );

app.get('/api/nbhbdm',function(req,res,err)
    console.log(req.query);
    var keyword = encodeURI(encodeURI(req.query.keyword));
    var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', "https://suo.im/api.htm?&key=000000000000&expireDate=2030-03-31&url=https://abcdef.cn/?s=" + keyword, true);
    httpRequest.send();
    httpRequest.onreadystatechange = function () 
        if (httpRequest.readyState == 4 && httpRequest.status == 200) 
            var result = httpRequest.responseText;
            console.log(result);
            res.json("status":"ok","slink":result,"nlink":https://abcdef.cn/?s=" + encodeURI(req.query.keyword));
        
        else
            res.json("status":"error","slink":"connection error","nlink":https://abcdef.cn/?s=" + encodeURI(req.query.keyword));
        
    
)
var server = app.listen(4008, '127.0.0.1', function()
    var host = server.address().address;
    var port = server.address().port;
    console.log("Server running at http://%s:%s", host, port);
)

我见过Error: Can't set headers after they are sent to the client,但我认为我没有尝试对同一个请求发送多个响应。 我能知道我的代码哪里出错了吗?

【问题讨论】:

【参考方案1】:
const User = require('../models/users')

const mongoose = require('mongoose')

here i am importing mongoose and user Schema it works for me

module.exports = 

      checkAuthenticated:(req,res,next)=>  // Check User Authentication
        if(req.isAuthenticated())
            return next()
        
        res.redirect('/login')
    


// 如果你的 checkAuthenticated 函数在不同的文件中所以请确保你已经导入了 User Schema 和 Mongoose

【讨论】:

【参考方案2】:

我看到了错误:在将标头发送到客户端后无法设置标头,但我认为我没有尝试对同一个请求发送多个响应。

你有,只是你没有注意到。

onreadystatechange事件被触发四次(1-4),一次 对于 readyState 中的每次更改。

来源:https://www.w3schools.com/js/js_ajax_http_response.asp

每次触发 onreadystatechange 并且 readyState 不是 4 或状态不是 200 时,您尝试使用 res.json() 向客户端发送响应。由于您不能对同一个请求发送多个响应,因此会引发错误。

您需要 onreadystatechange 回调来忽略任何不是 4 的 readystate,然后根据请求的状态采取行动:

httpRequest.onreadystatechange = function () 
    if (httpRequest.readyState !== 4)
        return;
    if (httpRequest.status == 200) 
        var result = httpRequest.responseText;
        console.log(result);
        res.json("status":"ok","slink":result,"nlink":https://abcdef.cn/?s=" + encodeURI(req.query.keyword));
    
    else
        res.json("status":"error","slink":"connection error","nlink":https://abcdef.cn/?s=" + encodeURI(req.query.keyword));
    

【讨论】:

以上是关于我收到“错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头”的主要内容,如果未能解决你的问题,请参考以下文章

我收到“错误:React.Children.only 预计会收到一个 React 元素子项。”带有 TouchableWithoutFeedback

当我没有收到手动运行代码时,在 Python for 循环中收到 KeyError

尝试控制台时收到 401~UNAUTHORIZED。记录我从 socket.io 收到的消息

无效的字典 0 )。为啥我收到此错误?

为啥我收到远程通知时没有发送本地通知?

我收到以下异常[重复]