Nodejs中mysql库的escape问题

Nodejs中mysql库的escape问题

我有一个buffer,我使用mysql提供的escape进行如下操作: con.escape( buffer.toString(‘binary’) ),通过这个将二进制数据存入数据库(mysql,字段数据类型为blob)。 现在的问题是: 从数据库内取这个数据,会比原始数据多十几个字节,什么原因,有人遇到过没,怎么解决的?

2 回复

Node.js 中 MySQL 库的 escape 问题

问题描述

你有一个 Buffer 对象,希望将其转换为字符串并使用 mysql 库中的 escape 方法存储到 MySQL 数据库中。具体操作如下:

const escapedValue = con.escape(buffer.toString('binary'));

然后将 escapedValue 存储到一个 BLOB 类型的字段中。

但是当你从数据库中取出这个数据时,发现取出的数据比原始数据多了十几个字节。你怀疑是因为 escape 方法对数据进行了某种处理导致的。

原因分析

在 Node.js 中,mysql 库的 escape 方法会对传入的数据进行转义处理,以防止 SQL 注入攻击。对于字符串,它会在两端添加单引号,并对特殊字符进行转义。然而,当处理二进制数据时,这种转义可能会导致额外的字节被添加。

解决方案

为了避免这种额外字节的出现,你可以直接使用 Buffer 的 toJSON 方法或直接将 Buffer 转换为十六进制字符串,而不是先转换为二进制字符串。这样可以避免不必要的转义字符。

示例代码

假设你有一个 Buffer 对象 buffer,你可以这样做:

// 将 Buffer 转换为十六进制字符串
const hexString = buffer.toString('hex');

// 直接存储十六进制字符串
const query = `INSERT INTO table_name (column_name) VALUES (?)`;
con.query(query, [hexString], (err, results) => {
    if (err) throw err;
    console.log("Data inserted successfully");
});

// 从数据库中读取数据
const selectQuery = 'SELECT column_name FROM table_name';
con.query(selectQuery, (err, results) => {
    if (err) throw err;
    const bufferFromDB = Buffer.from(results[0].column_name, 'hex');
    console.log("Buffer from DB:", bufferFromDB);
});

在这个例子中,我们首先将 Buffer 对象转换为十六进制字符串,然后直接将该字符串存储到数据库中。从数据库中读取数据时,再将十六进制字符串转换回 Buffer 对象。

这种方法可以确保数据在存储和读取过程中保持一致,不会因为转义操作而增加额外的字节。


当你使用 mysql 模块中的 escape 方法将 Buffer 转换为字符串,并存储到 MySQL 数据库中时,可能会遇到数据长度增加的问题。这是因为 toString('binary') 将 Buffer 转换为了一个包含 ASCII 码的字符串,而这些 ASCII 码在存储和读取过程中可能会引入额外的字符。

原因

  1. 转换为字符串buffer.toString('binary') 将 Buffer 中的每个字节转换为对应的 ASCII 字符。
  2. 存储与读取:存储时,这些 ASCII 字符被正常存储;读取时,如果处理不当,可能会导致额外的字符被加入。

解决方案

最好的方式是直接将 Buffer 存储到数据库中,避免不必要的转换。MySQL 支持直接存储二进制数据,使用 BLOB 类型即可。

示例代码

const mysql = require('mysql');

// 创建连接
const con = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'test'
});

// 打开连接
con.connect(err => {
  if (err) throw err;
  console.log('Connected!');

  // 示例 Buffer
  const buffer = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f]);

  // 直接插入 Buffer
  const sqlInsert = 'INSERT INTO my_table (data) VALUES (?)';
  con.query(sqlInsert, [buffer], (err, result) => {
    if (err) throw err;
    console.log('Data inserted');
  });

  // 查询 Buffer
  const sqlSelect = 'SELECT data FROM my_table WHERE id = ?';
  con.query(sqlSelect, [1], (err, result) => {
    if (err) throw err;
    console.log(result[0].data);
  });
});

关键点

  • 避免转换:不要使用 buffer.toString('binary') 进行转换。
  • 直接存储:直接将 Buffer 作为参数传递给 SQL 语句,mysql 模块会自动处理二进制数据的编码和解码。

通过这种方式,你可以确保从数据库读取的数据与原始数据完全一致,避免了额外字符的引入。

回到顶部