【问题标题】:javascript array as a list of strings (preserving quotes)javascript数组作为字符串列表(保留引号)
【发布时间】:2012-01-18 23:17:01
【问题描述】:

我有一个字符串数组。当我使用 .toString() 输出它时,引号不会保留。这使得使用“in”构建 mysql 查询变得困难。考虑以下几点:

SELECT * FROM Table WHERE column IN ('item1','item2','item3','item4')

toString is returning: IN (item1,item2,item3,item4)

我在这里忽略了一个简单的修复。

【问题讨论】:

  • 您正在用 JavaScript 准备 MySQL 查询? ... mmm ... SQL 注入
  • 你在使用服务器端的javascript吗?
  • 是的,除非这只是一个快速原型,否则您应该知道在客户端上形成 SQL 本质上是让任何人都可以完全访问您的数据库。不管是不是通过HTTPs,用户都可以打开调试器并注入。
  • 很抱歉破坏了您对 sql 注入的乐趣。我有一个内部全文搜索堆栈,它返回给我需要在 mysql 中查找的记录索引。 Node_Mysql 有一个错误,该错误会阻止正确传入数组,因此我正在寻找解决方法。我最终找到了一个尚未进入核心的补丁:github.com/felixge/node-mysql/issues/126

标签: javascript arrays node.js


【解决方案1】:

简单的解决方法是自己添加引号

for(var i=0; i<items.length; i++){
    items[i] = "'" + items[i] + "'";
}

var list_with_quotes = items.join(",");

请注意,我在这里完全忽略了 SQL 注入问题。

【讨论】:

    【解决方案2】:

    存储引号:

    var names = ["'item1'","'item1'","'item3'"];
    alert('IN (' + names[1] + ')'); // IN ('item1')
    

    【讨论】:

      【解决方案3】:

      引号不会保留,因为它们实际上不是字符串值的一部分,它们只是在代码中指示字符串文字所必需的。

      所以,不要使用toString()。相反,一种方法如下:

      var arr = ['item1','item2','item3','item4'];
      
      var quotedAndCommaSeparated = "'" + arr.join("','") + "'";
      
      // quotedAndCommaSeparated === "'item1','item2','item3','item4'"
      

      Array.join() 方法返回一个字符串,该字符串是将所有数组元素连接成一个字符串,每个项目之间有一个(可选)分隔符。因此,如果您指定包含引号和逗号的分隔符,您只需手动为第一项和最后一项(分别)附加开始和结束引号。

      (并且告诉我你没有使用客户端 JavaScript 来形成你的 SQL。)

      编辑:允许一个空数组,为结果字符串包含一个默认值,否则(如missingno所指出的)字符串将是"''"

      var newString = arr.length === 0 ? "" : "'" + arr.join("','") + "'";
      // default for empty array here ---^^
      

      (可能更适合使用if (arr.length===0) 来执行其他操作,而不是运行 SELECT 语句。)

      【讨论】:

      • 感谢您的建议。不,我不会为那些 sql 注入老鼠建立一些蜜罐来利用。
      • 空数组的正确行为应该是什么?空引号 ("''") 还是空字符串? ("")
      • @missingno - 好点。鉴于结果被连接到 SQL 字符串中,我不确定需要什么 - 可能最好不要运行 SELECT 语句。不过,很容易修复 - 我会更新我的答案......
      • 我花了 2 个小时,这个答案非常接近我所需要的,哈哈——无论如何,我试图保留数组中的引号,以便我可以将所有内容转换为 CSV 格式并使用逗号对于一些文字。我通过使用这个得到了这个: csv += '"' + row.join('","') + '"';
      • 如果项目中包含引号(或撇号),这将引发语法错误。确保对每个项目进行预处理。例如,为 postgres 加上双撇号。
      【解决方案4】:

      使用Array.map 将每个元素用引号括起来:

      items.map(function(item) { return "'" + item + "'" }).join(',');
      

      使用 ES6 功能,代码变得更简单 - 箭头函数和模板字符串(在 node.js 4.0 及更高版本中实现):

      items.map(i => `'${i}'`).join(',');
      

      您也可以使用白名单来防止 SQL 注入:

      const validItems = new Set(['item1', 'item2', 'item3', 'item4']);
      
      items
         .filter(i => validItems.has(i))
         .map(i => `'${i}'`)
         .join(',')
      

      【讨论】:

        【解决方案5】:
        let keys = ['key1','key2']
        let keyWithQoutes = keys.map((it) => {return `'${it}'`})
        let sql = `SELECT .... FROM ... WHERE id IN (${keyWithQoutes})`
        console.log(sql)
        

        输出:“SELECT .... FROM ... WHERE id IN ('key1','key2')”

        【讨论】:

          猜你喜欢
          • 2014-05-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-04
          • 1970-01-01
          相关资源
          最近更新 更多