Node.js操作MySQL中文乱码的根本原因是客户端、连接层、服务端字符集未统一为utf8mb4;需在mysql2连接配置中显式设置charset: 'utf8mb4',确保MySQL服务端character_set_server等变量及init_connect均为utf8mb4,并对外部输入(如GBK文件)用iconv-lite显式转码。

Node.js 实战项目中操作 MySQL 出现中文乱码,根本不是某一行代码写错了,而是 Node.js 客户端、MySQL 连接层、服务端三者之间在「说哪种语言」这件事上没对齐。只要其中一环用 UTF-8,另一环默认用 latin1 或 GBK,中文就立刻变成 ??? 或 测试。
MySQL 连接初始化时没声明 utf8mb4
这是最常见也最容易被忽略的一环。Node.js 的 MySQL 驱动(比如 mysql2)建立连接时,默认不主动协商字符集,而是依赖 MySQL 服务端的全局配置 + 客户端启动参数。如果服务端没强制设 init_connect,而你又没在连接选项里显式指定,那这一整条连接链路默认就是 latin1。
- 错误表现:
INSERT INTO user(name) VALUES('张三')成功,但SELECT * FROM user返回??? - 正确做法:连接配置中必须加
charset: 'utf8mb4'(注意是utf8mb4,不是utf8) - 示例(
mysql2):const pool = mysql.createPool({<br> host: 'localhost',<br> charset: 'utf8mb4'<br>}); - 漏掉这个,哪怕数据库、表、字段全设成
utf8mb4,照样乱码
Node.js 写入前没处理 Buffer 编码或字符串拼接
当 SQL 语句里混入动态拼接的中文字符串(比如 WHERE name = '${name}'),而 name 来自文件读取、HTTP 请求体或旧系统接口,它本身的编码可能不是 UTF-8。Node.js 的 Buffer.toString() 默认按 UTF-8 解,但如果原始 Buffer 是 GBK 编码,就会错解。
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
- 典型场景:
fs.readFileSync('data.txt')读了一个 Windows 记事本保存的 GBK 文件,直接插进 SQL - 解决方案:不用
toString()硬转,改用iconv-lite显式解码:const iconv = require('iconv-lite');<br>const buf = fs.readFileSync('data.txt');<br>const str = iconv.decode(buf, 'gbk'); - 更安全的做法:所有外部输入统一转成 UTF-8 字符串再进 SQL,别依赖默认行为
MySQL 服务端未启用 utf8mb4 全链路支持
只改 Node.js 代码或连接参数,解决不了底层握手失败。MySQL 有五个关键变量控制字符流走向:character_set_client、character_set_connection、character_set_results、collation_connection、init_connect。任意一个不是 utf8mb4,Node.js 发过去的中文就会在中间被截断或误转。
- 验证命令:
SHOW VARIABLES LIKE 'character\_set%';和SHOW VARIABLES LIKE 'collation%'; - 必须确保:
character_set_server、collation_server是utf8mb4,且init_connect包含SET NAMES utf8mb4 - 配置示例(
my.cnf):[mysqld]<br>character-set-server = utf8mb4<br>collation-server = utf8mb4_unicode_ci<br>init_connect = 'SET NAMES utf8mb4'
- Windows 下还要确认终端代码页不是
GBK(chcp 65001切到 UTF-8),否则连mysql -u root -p都会干扰 Node.js 连接行为
真正卡住人的地方,往往不是某个配置没改,而是改了 A 却忘了 B —— 比如设好了 charset: 'utf8mb4',却没动 MySQL 的 init_connect;或者数据库全设对了,但 Node.js 读文件时用的是 fs.readFileSync(path, 'utf8'),而文件本身是 GBK。每个字节流动的边界,都得亲手把关。

















