0

I am using Node.js and multer to upload a zipped file and save it to MySql database. I have succeeded in creating a login function whereby users can register, login, maintain a session key, and all is saved to the MySql DB.

When I try to upload the zip file and post it to my route and query it to the database, it doesnt work and says the upload object is undefined.

EDIT: The zipped file uploads and saves to the /upload folder as defined in the storage path in the multer function I added below, so it is working that far. I believe the problem could be in the post request in the JS code above the upload form, and/or in the async function.

EDIT:

//this is the error I receive, however i do not believe there is an issue with the db query itself, I believe it's an issue with the req.body object defined in the async function.

  code: 'ER_PARSE_ERROR',
  errno: 1064,
  sqlMessage:
   '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 \'\'undefined\', \'undefined\', \'undefined\'\' at line 1',
  sqlState: '42000',
  index: 0,
  sql:
   'INSERT into user_v_file (user_vile,vile_name,vile_desc) VALUES \'undefined\', \'undefined\', \'undefined\'' }

//This is the upload form and post request:

<script>
$(document).ready(function() {
  $("#upload").click(function() {
    $("#form-upload").toggle();
    });
    $('#uploadVr').click(function(e){
        $.post("http://localhost:3000/upload",{
                    user_vile : $("#uservile").val(),
                    vile_name : $("#vilename").val(),
                    vile_desc : $("#viledesc").val()
                    },function(data){
                if(!data.error) {
                    window.location.href = "/home";
                } else {
                    alert(data.message);
                }
            });
        })
});
</script>
</head>
<body>
    <button type="button" id="upload" value="Upload">Upload</button>
    <button onclick="window.location.href='/home.html'" type="button" id="explore" value="Explore">Explore</button>

    <form id="form-upload" action="/upload"  method="POST"  enctype="multipart/form-data" style="display:none">
        Upload folder: <input type="file" id="uservile" name="vr_files">
        VR name: <input type="text" id="vilename">
        VR description: <input type="text" id="viledesc">
        <input type="submit" id="uploadVr " value="Uploadfiles"/>
    </form>
</body>
// this is async function
const upload = async (req, res) => {
  try {
    const {vile_name, vile_desc} = req.body;
    const {user_vile} = req.file;
    const resp = await db.upload(user_vile, vile_name, vile_desc); //should it be vr_file..?
    req.session.key = resp;
    res.send({error: false, message: "Vile added"});

  } catch (e) {
    res.send({error: true, message: "Vile upload failed"})
    console.log(e);
  }
  console.log(req.body);
  };
//this is the multer function to define upload storage path 
var storagePath = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, './files/uploads')
    },
    filename: function (req, file, cb) {
      cb(null, file.fieldname + '-' + Date.now())
    }
  })
var upload = multer({storage: storagePath})
// this is the route 

router.post('/upload', upload.single('user_vile'), main.upload);

//this is the DB query


const upload = async (user_vile, vile_name, vile_desc) => {
  const results = await testDb.query(`INSERT into user_v_file (user_vile,vile_name,vile_desc) VALUES '${user_vile}', '${vile_name}', '${vile_desc}'`);
  return results
};
Nancy Collins
  • 157
  • 2
  • 9
  • 1
    *doesn't work* is quite vague. What exactly doesn't work? Does the request arrive at the backend at all? Can you sucessfully post using another client, e.g. postman (or in other words: Is the error on the clientside)? So you get any errors? – Jonas Wilms Aug 20 '19 at 13:36
  • Sorry, I have edited my question to better explain and added the error message and multer storage definition. – Nancy Collins Aug 20 '19 at 14:59

1 Answers1

1

All inputs need to have a name, however multiple of the inputs (namely the ones that arrive with undefined at the server) don't have one:

 <input type="text" id="vilename" name="vile_name" />

Yes, you do have a jQuery handler that tries to intercept the form post, and that makes an AJAX post request instead with the correct format, however that AJAX request will never run, as you do not cancel the form submit. To do so, call e.preventDefault() in the click handler.

And please make sure to prevent these SQL Injections. You are really creating a security risk with your current code.

Jonas Wilms
  • 106,571
  • 13
  • 98
  • 120
  • I've just updated my async function. Now, when I console.log(req.body) it logs the values from the two text inputs from the form, so it's just the zipped file it cannot read. If you'd like to call it a day that's fine you have helped me out a lot! – Nancy Collins Aug 20 '19 at 17:41
  • 1
    Yeah, the file will be on `req.files` not on `req.body` (if I understand the multer docs correctly) – Jonas Wilms Aug 20 '19 at 17:44
  • Yeah it now says "TypeError: Cannot destructure property `user_vile` of 'undefined' or 'null'.".. Thank you for trying!! – Nancy Collins Aug 20 '19 at 17:50