Node.js向MySQL插入含特殊字符的JSON数据报错如何处理?
问题描述
成功插入了description1,但插入包含%的description2和包含单引号'的description3时出现报错。MySQL表中description列的数据类型为JSON。
原代码示例:
let description1 = { text: { data: Click Here, size: 36, alignment: center }, others: something string }; let description2 = { text: { data: Click rate 30%, size: 36, alignment: center }, others: something string }; let description3 = { text: { data: Click Here, size: 36, alignment: center }, others: something special alamin's string }; let dbConf = { connectionLimit: parseInt(DB_POOL_MAX), host: DB_HOST, user: DB_USERNAME, password: DB_PASSWORD, database: DB_DATABASE, multipleStatements: true }; const dbConnection = makeDb(dbConf); const dbConnectionObject = util.promisify(dbConnection.query).bind(dbConnection); let sql = `INSERT INTO product_description (product_id, description) VALUES ('${pdid}','${JSON.stringify(description})')`; let result = await dbConnectionObject(sql);
解决方案
问题出在你直接用字符串拼接生成SQL语句,这种方式既会导致特殊字符转义失败,还存在SQL注入风险。针对MySQL的JSON列,正确做法是用参数化查询,让数据库驱动自动处理转义逻辑。
修改后的代码:
// 先修正原代码中字符串值的引号问题(JavaScript对象的字符串必须加引号) let description1 = { text: { data: "Click Here", size: 36, alignment: "center" }, others: "something string" }; let dbConf = { connectionLimit: parseInt(DB_POOL_MAX), host: DB_HOST, user: DB_USERNAME, password: DB_PASSWORD, database: DB_DATABASE, multipleStatements: true }; const dbConnection = makeDb(dbConf); const dbConnectionObject = util.promisify(dbConnection.query).bind(dbConnection); // 使用?作为参数占位符,避免字符串拼接 let sql = `INSERT INTO product_description (product_id, description) VALUES (?, ?)`; // 将参数放入数组,驱动自动处理转义 let result = await dbConnectionObject(sql, [pdid, JSON.stringify(description1)]);
核心要点:
- 用
?替代SQL语句中的变量,不要直接把变量拼进字符串里。 - 把需要插入的参数(
pdid和序列化后的JSON字符串)放进数组,传给query方法。MySQL驱动会自动处理所有特殊字符的转义,包括单引号'、百分号%等。 - JSON列只需要把JS对象转成JSON字符串(
JSON.stringify)后作为参数传入即可,驱动会正确处理转义并写入JSON列。
为什么原代码会报错?
- 当
description3里有单引号'时,拼接后的SQL会变成:VALUES ('xxx','{"others":"something special alamin's string"...}'),这里的单引号会打断SQL的字符串边界,直接导致语法错误。 - 百分号
%本身是SQL通配符,直接拼接时可能被MySQL误解析,不过最致命的还是单引号这类破坏语句结构的字符。
内容的提问来源于stack exchange,提问作者Md. Al Amin Bhuiyan
相关产品推荐
相关产品推荐

