我有一个ajax请求,它向表中添加一个或多个记录(以下代码是服务器端的):

app.post('/saveLesson',function(req, res) {

    let sections = JSON.parse(req.body.sections);

    let sql = 'INSERT INTO sections (title, content, duration) VALUES ';

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

        if (i == sections.length-1) {
            sql += '("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '");';
        } else {
            sql += '("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '"),';
        }
    }
    connection.query(sql,
        function (error, result) {
            if (error) throw error;
    });

});

我想阻止SQL注入,但我不确定如何对多个记录执行此操作。
一般来说,我知道我必须按照以下方式构建sql语句:
connection.query("SELECT * FROM bank_accounts WHERE dob = ? AND bank_account = ?",
    [
     req.body.dob,
     req.body.account_number
    ],
    function(error, results) {

    }
);

但我不知道如何通过多个记录(不知道它们有多少)来实现这一点。.query参数只是一个正则数组吗?
另外,我需要将创建的id存储在某个地方,并将它们发送回客户机页面。我怎样才能做到这一点?谢谢您。
*****************************更新*****************************
虽然有人发布了一个解决方案,但我认为这可能是有用的。通过下面的代码,您可以添加多个记录来防止SQL注入。
app.post('/saveLesson',function(req, res) {

    let sections = JSON.parse(req.body.sections);

    console.log(sections);

    let sql = 'INSERT INTO sections (title, duration, content) VALUES ';

    // I make a new array to pass the list of values to the query
    let sectionsParamList = [];

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

        if (i == sections.length-1) {
            sql += '(?,?,?);';
        } else {
            sql += '(?,?,?),';
        }

        sectionsParamList.push(sections[i].title);
        sectionsParamList.push(sections[i].duration);
        sectionsParamList.push(sections[i].content);
    }

    connection.query(sql, sectionsParamList,
        function (error, result) {
            if (error) throw error;
    });

});

最佳答案

MySQL的工作方式是,当您执行像您建议的那样的多行INSERT操作时,只会返回自动生成的最后一行的uniqueid。它在result对象中显示为result.insertId。不要试图猜测其他行的id值,例如通过减法,因为这是没有保证的。
对于插入的每一行,您都需要id这一事实意味着您不应该使用多行插入,而应该使用一系列单行插入。这也巧妙地解决了SQL注入问题。
但你必须弄清楚如何进行一系列INSERT操作。您可能需要使用async/await/promise设置来完成。像这样的东西,没有调试。

/* do one insert with a Promise so you can await it */
function doInsert (section, connection) {
   const values = [section.title, section.content, section.duration];
   return new Promise( function ( resolve, reject ) {
      const sql = "INSERT INTO sections (title, content, duration) VALUES (?,?,?);"
      connection.query (sql, values, function ( error, result ) {
         if (error) reject (error)
         resolve (result.insertId)
      } )
   } )
}

/* do all the inserts, awaiting each one */
async function doInserts (sections, connection) {
  let ids = []
  for (let i = 0; i < sections.length; i++) {
     const id = await doInsert (sections[i], connection)
     ids.push(id)
  }
  return ids
}

/* handle your post */
app.post('/saveLesson',function(req, res) {
  let sections = JSON.parse(req.body.sections)
  /* get the result back from an async function with .then / .catch */
  doInserts (sections, connection)
  .then (function (resultIds) {
     /* respond with the id values in a JSON object */
     res.status(200).json(resultIds)
  } )
  .catch ( function (error) {
     /* respond with an error */
     res.status(500).json(error)
  } )
} )

如果你还不知道这些异步/等待和承诺语言结构,那么它们确实值得你费劲去学习。

关于javascript - 使用NodeJS在mySQL中插入多个记录以防止注入(inject)并获取每个记录的ID,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56359521/

10-09 19:28