最近学node时,使用Express时,后台服务器终端遇到了Can’t set headers after they are sent.问题
问题描述
系统:Windows 7 x64
Node.js版本:版本是:v8.16.0
一段后端模拟HTTP请求的代码出现以下错误:Error: Can’t set headers after they are sent.
翻译:不能在发送后设置报头。
截图如下:
此时我的后台服务器代码是这样的
/*
* @Author: bkk
* @weixin: biankuan1996
* @email: [email protected]
* @Date: 2021-06-17 11:06:12
* @LastEditTime: 2021-06-17 11:55:47
*/
const express = require('express');
var app = express();
// 所有的请求
app.all("*",function (req,res,next) {
// 相当于域名白名单,不能写 * ,因为 * 是通配符 所有网站都可以访问
res.setHeader('Access-control-Allow-Origin','*')
res.setHeader('Access-control-Allow-Headers','X-request-Width')
// ...Headers必须的固定值
res.setHeader('Access-control-Allow-Methods','GET,POST,DELETE,PUT,OPPINS')
// 下一步
next()
})
// 中间件 扩展了req.body功能
// 所有中间件 一般都写到 请求的最上方
app.use(express.urlencoded({
extended:true}))
// 给每个请求加一个时间戳
app.use(/.*/,function (req,res,next) {
// 加一个本地时间
console.log(new Date().toLocaleString());
// 不要忘记 next
next();
})
app.get("/home",(req,res)=>{
res.json({
code:1000,
msg:"成功"
})
})
// -------jsonp 也是get请求
app.get("/ajaxJsonp",(req,res)=>{
console.log("jsonp参数:",req.query);
// 只有jsonp请求 对应返回用的是jsonp
let{
name,pwd} = req.query;
if (name === "雨航" && pwd === "yh163.com") {
res.jsonp({
code:1000,
msg:"jsonp-成功"
})
} else {
res.jsonp({
code:1000,
msg:"jsonp-失败"
})
}
})
// -------get
app.get("/ajaxGET",(req,res)=>{
console.log("get参数:",req.query);
// 只有jsonp请求 对应返回用的是jsonp
let{
name,pwd} = req.query;
if (name === "雨航" && pwd === "yh163.com") {
res.json({
code:1000,
message:"get-成功"
})
} else {
res.json({
code:1000,
message:"get-失败"
})
}
})
// -------post
// express 接收到的post请求数据 都存储在req对象的body属性里
app.post("/ajaxPOST",(req,res)=>{
console.log("post参数:",req.query);
console.log("post参数-2:",req.body);
let{
name,pwd} = req.body;
if (name === "雨航" && pwd === "yh163.com") {
res.json({
code:1000,
message:"post-成功"
})
} else {
res.json({
code:1000,
message:"post-失败"
})
}
// 只有jsonp请求 对应返回用的是jsonp
// 经过排查 是因为多写了这段代码,下面的res.json()删掉/注释掉
res.json({
code:1000,
message:"post-成功"
})
})
app.listen(9201,()=>{
console.log("9201 启动");
})
经过排查之后发现是最后一个
res.json({
code:1000,
message:“post-成功”
})
这里使服务器爆出了多次调用Serverresponse.json错误,把这段代码注释掉之后,报错就会消失
原因是:
res.json内置了writeHeader方法,我们多执行了一次res.json,就相当于多写了一次writeHeader,但上一个res.json已经把数据发送给客户端,我们再一次执行res.json,又要执行一次writeHeader,所以才会报错:Can’t set headers after they are sent.
前端页面代码是这样的
<!--
* @Author: bkk
* @weixin: biankuan1996
* @email: [email protected]
* @Date: 2021-06-16 16:03:59
* @LastEditTime: 2021-06-17 11:11:09
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js"></script>
</head>
<body>
<input type="text" placeholder="请输入用户名" id="username">
<input type="text" placeholder="请输入密码" id="userpwd"><br>
<button>get</button>
<button>post</button>
<button>jsonp</button>
<script>
// get
$('button').eq(0).click(function(){
$.ajax({
type: "get",
url: "http://127.0.0.1:9201/ajaxGET",
data: {
name:username.value,
pwd:userpwd.value
},
dataType: "json",
success: function (response) {
console.log("get---",response);
alert(response.message)
}
});
})
// post
$('button').eq(1).click(function(){
$.ajax({
type: "post",
url: "http://127.0.0.1:9201/ajaxPOST",
data: {
name:username.value,
pwd:userpwd.value
},
dataType: "json",
success: function (response) {
console.log("post---",response);
alert(response.message)
}
});
})
// get
$('button').eq(2).click(function(){
$.ajax({
type: "get",
url: "http://127.0.0.1:9201/ajaxJsonp",
data: {
name:username.value,
pwd:userpwd.value
},
dataType: "jsonp",
jsonpCallback:"getData"
});
})
function getData(data) {
console.log("jsonp------:",data);
alert(data.msg)
}
</script>
</body>
</html>