【问题标题】:How can I escape an apostrophe to match data from a MySQL database in Node.js/Discord.js?如何在 Node.js/Discord.js 中转义撇号以匹配 MySQL 数据库中的数据?
【发布时间】:2019-11-12 02:07:43
【问题描述】:

我知道转义通常是如何工作的,但在这种情况下,我无法让它给我想要的结果。

我有一张桌子,里面有一张卡片列表。在命令的顶部,我让查询将每个卡名称作为“主列表”推送到一个数组中。稍后在代码中,我让用户提供他们想要添加到他们的牌组中的卡片名称。为了检查他们使用的卡片是否存在,拼写完全一样,它会获取用户提供的每个卡片名称,并尝试在主列表数组中找到它。

但是,当用户提供带有撇号的卡片名称(即Drago's Fury)时,它会拒绝在列表中找到卡片名称。

我尝试将所有出现的' 替换为\''' 以及两者的几种组合,多个\'s 和多个' 's,数量不等。似乎没有什么能让我匹配它。表中的Drago's Fury 确实包含名称中的's,因为我可以通过使用\' 转义它来将其放入表中。

这是我的代码:

con.query(`SELECT * FROM cardsmaster`, (error, rows, fields) => {
    let cardsList = []
    for (var i in rows) {
        cardsList.push(rows[i].name)
    }
});

Drago's Fury 在 MySQL 表中的列出方式如下:

当用户在 Discord 中提供 Drago's Fury 时,我现在正在使用它来尝试逃避它:

cardsToAdd = cardsToAdd.content.replace(/'/gi, "\'");

这是cardsToAdd 在替换后记录时显示Drago's Fury 的方式:

然后我收到此错误:

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 's Fury, Fierce Boost, Fierce Boost, Fiery Rage, Fire Boost, Fire Boost, Magma Bo' at line 1

所以,我尝试了:

cardsToAdd = cardsToAdd.content.replace(/'/gi, "\\'");

我在想第一个 \ 会避开第二个 \ 和撇号,但这并不是我想要的。传入的值是相同的,只是它有双引号而不是单引号,所以我不确定这是否导致了问题......

这是尝试获取用户提供的内容并在主列表中找到它的部分:

let usercardnamearray = cardsToAdd.split(", ")

let matchedcards = []
let unmatchedcards = []

for (let i = 0; i < usercardnamearray.length; i++) {

    console.log(usercardnamearray[i])

    let found = cardsList.indexOf(`${usercardnamearray[i]}`)
    console.log(found)

    if (found >= 0) {
        matchedcards.push(usercardnamearray[i])
    } else if (found == -1){
        unmatchedcards.push(usercardnamearray[i])
    }
}

我如何才能始终如一地匹配主列表中提供的名称?

【问题讨论】:

  • 您的代码易受 SQL 注入攻击。看看使用准备好的语句。这也将解决您的问题。
  • @frobinsonj 那么,您是否建议我使用 ?'s 作为占位符?我不完全明白这将有什么帮助,因为首先通过 indexOf 使用列表检查用户提供的内容,这会过滤掉不可接受的输入?我可能只是错过了这里的重点。你能详细说明一下吗?
  • 通过使用占位符 (?),输入会自动为您转义。这将防止注入和您当前的错误,而无需您自己做任何其他事情。
  • 好的,我想我明白了。我以前以这种格式使用过类似的东西。 i.gyazo.com/5f78ea354de8213664e33f708cf7226e.png 这会按照您的建议进行吗?我运行它,现在找不到任何结果,但我认为这只是我更新代码以适应更改的问题。
  • 好的,我在命令顶部的cardList变量中做了那个,看起来在列表中查找卡片时,它正在找到它!稍后在 INSERT 查询中也对其进行了更改,并且它也可以完美运行!非常感谢! @JackRed 如果您想将您的建议作为答案发布,我会将其标记为正确。谢谢你和懒惰的人!

标签: mysql node.js discord.js


【解决方案1】:

如 cmets 中所述,通过使用占位符 (?),输入会自动为您转义; node-mysql 驱动程序自己使用mysql.escape()。这将防止注入和您当前的错误,而您不必自己做任何其他事情。您的撇号不会触发相同的错误,因为它是按字面意思阅读的,而不是作为语句的一部分。

示例用法:

const name = "Drago's Fury";

con.query("SELECT * FROM cardmaster WHERE name = ?", [name], (err, rows) => {
  if (err) return console.error(err);

  console.log(rows);
})

【讨论】:

    猜你喜欢
    • 2012-03-24
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2011-05-23
    • 1970-01-01
    相关资源
    最近更新 更多