• 基于Node.js API开发:Error [ERR_HTTP_HEADERS_SENT]


    问题

    最近在用Node.js开发接口,使用的库主要是node+express+mysql2,在测试时出现如下错误:

    Error [ERR_HTTP_HEADERS_SENT]: 
    Cannot set headers after they are sent to the client
    
    # 报错的字面意思就是: 已经响应客服端请求后不能再设置headers了
    
    • 1
    • 2
    • 3
    • 4

    也就是说同一个请求不能同时两次使用 res.send 方法。

    我的代码如下:

    // 用户注册
    exports.register = (req, res) => {
    	// 接收表单数据
    	const data = req.body
    	
    	// 数据校验
    	if (!data.username || !data.password) {
    	  return res.send(result(1, '用户名或密码不能为空!', data))
    	}
    	
    	// 重复校验
    	const select = `select * from dc_user where username=?`
    	db(select, [data.username], function (err, results) {
    	  if (err) {	// SQL异常
    	    return res.send(result(1, err.message))
    	  } else if (results.length > 0) {		// 重复
    	    return res.send(result(1, '用户名已存在!', results))
    	  }
    	  
    	})
    	
    	// 创建用户
    	const create = `insert into dc_user(username, password) values(?, ?)`
    	db(create, [data.username, data.password], function (err, results) {
    		
    		if (err) {	// SQL异常
    			return res.send(result(1, err.message))
    		} else {	// 注册成功
    			return res.send(result(0, '注册成功!', results))
    		}
    	  
    	})
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    分析

    在网上看了一下类似的问题,很多说是 res.send 使用错误,每个res.send 前都应该加上 return 我这里其实是不存在这个问题,也没有逻辑上的低级错误。
    后来看了一篇分析跟我的问题很像:也就是我这里的 db 查询是异步的,两个 db 平行执行会有两次 res.send 返回,所有才会报错。

    解决

    找到问题就很好解决了,将两次查询嵌套即可,代码如下:

    // 用户注册
    exports.register = (req, res) => {
    	// 接收表单数据
    	const data = req.body
    	
    	// 数据校验
    	if (!data.username || !data.password) {
    	  return res.send(result(1, '用户名或密码不能为空!', data))
    	}
    	
    	// 重复校验
    	const select = `select * from dc_user where username=?`
    	db(select, [data.username], function (err, results) {
    	  if (err) {	// SQL异常
    	    return res.send(result(1, err.message))
    	  } else if (results.length > 0) {		// 重复
    	    return res.send(result(1, '用户名已存在!', results))
    	  } else {
    		  // 创建用户
    		  const create = `insert into dc_user(username, password) values(?, ?)`
    		  db(create, [data.username, data.password], function (err, results) {
    		  	
    		  	if (err) {	// SQL异常
    		  		return res.send(result(1, err.message))
    		  	} else {	// 注册成功
    		  		return res.send(result(0, '注册成功!', results))
    		  	}
    		    
    		  })
    	  }
    	  
    	})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    参考资料

    https://blog.csdn.net/m0_46635519/article/details/123599923

  • 相关阅读:
    python对excel数据表进行数据清洗
    软考考后常见问题详解~
    【C语言】快速排序__拓展
    Cocos Creator TypeScript 套牛游戏
    【嵌入式开发 Linux 常用命令系列 8 --代码格式修改工具 astyle】
    Go 基本数据类型和 string 类型介绍
    (附源码)小程序+spring boot宠物健康管理系统 毕业设计 201738
    75. 颜色分类(中等 数组 双指针 排序)
    智云通CRM:产品销量和价格有什么关系?
    基于Laravel封装一个强大的请求响应日志记录中间件
  • 原文地址:https://blog.csdn.net/gaoshanliushui131/article/details/126948600