【问题标题】:How to escape double and single quotes in a JSON array如何在 JSON 数组中转义双引号和单引号
【发布时间】:2020-10-21 19:06:17
【问题描述】:

我正在尝试创建一个聊天系统,每次有人发送消息时,它都会被添加到我数据库中那个特定人的 JSON 数组中,但我遇到的问题是当有人尝试使用双引号时" " 或在他们的消息中单引号 '。每当添加带有这些特殊字符的消息时,我都会收到错误消息:ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near。我在网上找了类似的问题,他们都说我需要用\" 转义双引号,但是当我使用JSON.stringify 方法时,我已经这样做了。

不幸的是,这在 JSON 数组中不起作用,而是我不得不用 \\" 替换双引号,但是当我使用 JSON.parse 方法时,我在输出中看到了反斜杠。如果我只使用一个斜杠,我会得到一个 SQL 解析错误。

正在发送的消息具有 ID、时间戳、消息和发送者的姓名。 [{"ID": 1, "Timestamp": "10/20/2020 11:00 AM", "Msg": "Hello There", "Name": "John"}]

我正在尝试的一个示例如下:

let previousMessages = JSON.parse(this.state.Messages);
let newMsg = `testing double "quotes" and single quote's`
previousMessages.push({ID: previousMessages.length+1, Timestamp: new Date(), Msg: newMsg.replace(/"/g,'\\"'), Name: "John"});

对我的数据库的查询如下所示:

UPDATE table1 SET Messages = "${JSON.stringigy(previousMessages)}" WHERE ID = '1';
// output: UPDATE table1 SET Messages = "[{"ID":1,"Name":"John","Msg":"testing double \\\"quotes\\\" and single quote's","TimeStamp":"10/20/2020 11:00 AM"}]" WHERE ID = '1';

我收到的错误是这样的:

Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ID":1,"Name":"John","Msg":"testing double \\\"quotes\\\" and single quote's","T' at line 2

我尝试过的事情

我尝试将引号替换为其他字符,例如将 ' 替换为 _,这很有效,但似乎每次我想创建消息时都必须这样做。

我也尝试在我的 SQL 查询中使用单引号而不是双引号,如下所示:UPDATE table1 SET Messages = '${JSON.stringify(previousMessages)}' WHERE ID = '1'; 但这并没有什么不同

如果有人知道如何在 JSON 数组中转义这些字符的好方法,那将非常有帮助。我觉得必须有一种更简单的方法来转义这些字符,而不是必须为每个字符设置两个不同的 replace 方法。

【问题讨论】:

  • 只是取出 JSON.stringify() 函数,因为它已经是一个字符串了?
  • @SweetChillyPhilly 它需要被字符串化,因为它是我传递给我的数据库的对象。
  • @MauriceMeyer 如果我不在 JSON 数组中用 \\" 替换双引号,我最终会出错。对 JSON 数组进行字符串化时,需要在其中添加双斜杠。

标签: javascript mysql json


【解决方案1】:

如果您是直接编写 SQL,那么给定一个有效的 JSON 文本,您需要:

  • 用单引号括起来
  • 转义其中的任何单引号
  • 转义所有转义序列

你不需要用双引号做任何事情。

所以 JSON:[1, "John O'Brian", { "hello": "world" }]

会变成Messages='[1, "John O\'Brian", { "hello": "world" }]'


如果你想用 JS 生成它,那么它看起来像:

const array = [1, "John O'Brian", { "hello": "world" }];
const json = JSON.stringify(array);
const sql = `UPDATE table1 SET Messages='${json.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}' ...`

……但你不应该那样做。

使用允许您使用占位符并将其留给数据库引擎来确定如何使用引号的 API。它更简单、更不容易出错且更安全。

例如使用 NPM 的 mysql 模块:

const array = [1, "John O'Brian", { "hello": "world" }];
const json = JSON.stringify(array);
connection.query(
    "UPDATE table1 SET Messages=? ....",
    [ json ],
    function (error, results, fields) {

     });

【讨论】:

  • 那么如果用户在这条消息中输入:double "quotes" single quote's and a return line\n?我是否必须替换双引号、撇号和换行符?必须替换字符串中的每个特殊字符才能被接受似乎很荒谬。
  • @Michael — 不。但正如我所说,使用占位符,您无需担心。重新发明“如何为数据库转义数据”工具是没有意义的,这是一个很好解决的问题。
  • 好的,我尝试了占位符的方式,看起来它接受了这些。谢谢你的回答。
【解决方案2】:

从 MYSQL 5.7.8 开始,已经支持 JSON 数据类型(由 RFC 7159 定义,read more)。关于引号字符,您有 2 个选项;首先是像这样使用JSON_OBJECT 定义:

UPDATE table1 SET Messages = JSON_OBJECT("message", "quoted \"Value\".");

或者通过 JSON 对象字面量设置(正如您已经体验过的,必须从 JS/后端确保语法正确):

UPDATE table1 SET Messages = ('{"message": "quoted \\"Value\\"."}');

如前所述,更好的解决方案例如是使用来自后端的准备好的语句参数/值绑定。如果你的后端是用 PHP 实现的,here you can read about it.

【讨论】:

    【解决方案3】:

    下面的代码去掉引号

    SET @user_name = JSON_UNQUOTE(JSON_EXTRACT(jsonText,'$.name'));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-13
      • 2013-06-30
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 2011-11-22
      • 2013-03-16
      相关资源
      最近更新 更多