You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js连接MySQL报PROTOCOL_ENQUEUE_HANDSHAKE_TWICE错误如何解决

报错原因

PROTOCOL_ENQUEUE_HANDSHAKE_TWICE报错的根本原因就是你对同一个数据库连接实例重复调用了connect()方法。通过mysql.createConnection()创建的连接对象,只需要执行一次握手连接,之后可以直接多次调用query()执行SQL语句,不需要重复建立连接。

修复方案

推荐直接使用数据库连接池代替单次创建连接,连接池会自动管理连接的复用、销毁,并发场景下性能和稳定性更高,同时也能避免重复连接的问题。修改后的mysql.js代码如下:

// 导入mysql库
import mysql from "mysql"

// 创建数据库连接池
const pool = mysql.createPool({
    host: "localhost",
    user: "root",
    password: "*******",
    database: "store_user_info",
    connectionLimit: 10 // 可根据业务需求调整连接数上限
})

export let run_db = (insert_values, callback) => {
    // 从连接池获取可用连接
    pool.getConnection((err, db_connect) => {
        if (err) throw err
        
        // 校验邮箱/用户名是否存在,直接加WHERE条件查询,不用查全表性能更高
        const checkSql = `SELECT * FROM Users WHERE email = ? OR username = ?`
        // 使用参数化查询,避免SQL注入漏洞
        db_connect.query(checkSql, [insert_values.email, insert_values.username], (err, result) => {
            if (err) {
                db_connect.release() // 操作完成释放连接回连接池
                throw err
            }
            if (result.length > 0) {
                console.log("email/username已被占用")
                db_connect.release()
                callback?.({status: 'fail', msg: '邮箱或用户名已被占用'})
                return
            }
            // 校验通过执行插入
            const insertSql = `INSERT INTO Users (email,password,username) VALUES (?, ?, ?)`
            db_connect.query(insertSql, [insert_values.email, insert_values.password, insert_values.username], (err, result) => {
                db_connect.release()
                if (err) throw err
                console.log("用户注册成功")
                callback?.({status: 'success', msg: '注册成功'})
            })
        })
    })
}

对应修改express.js中的路由逻辑,增加返回响应给前端,避免前端请求超时:

// 原路由命名和实际功能不符,建议修改为/register
app.post('/register', (req, res) =>{
    const json_db_value = {
        "email": req.body.email.toString(),
        "password": req.body.password.toString(),
        "username": req.body.username.toString()
    }
    run_db(json_db_value, (result) => {
        res.json(result)
    })
})
其他优化建议
  • 不要明文存储用户密码,推荐使用bcrypt等加密库对密码加盐哈希后再存入数据库,避免数据泄露后用户密码明文外泄
  • 原代码中直接拼接SQL字符串的写法存在SQL注入风险,一定要使用参数化查询的写法传递查询参数

内容的提问来源于stack exchange,提问作者mythic lisp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:36:04