Using Nodejs (fs) to access files selected with input type=file

file, fs, input, node.js, sftp

Solution

Okay, I seem to have solved my own problem. For anyone that faces this problem in the future I will give a rough outline to my solution.

I needed to add: `enctype="multipart/form-data"` to my form. I had previously tried this, but I didn't understand what I needed to change on the server side. Using the nodejs module: https://github.com/andrewrk/node-multiparty I could parse the form data into a readable object. My server side code then became something like this:

router.post('/upload', function(req,res) {
// Create a new connection
var fs = require('fs');
var multiparty = require('multiparty');
var util = require('util');
var Connection = require('ssh2');
var c = new Connection();
// Get the files to be uploaded
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
    // Each element of the object is an array
    console.log("form parsed");
    // yamlfiles is an array anyway
    var yamlfiles = files.yamlfiles;
    // username is just a text field, so the 0th element is username
    var uname = fields.username[0];
    // files is a single file, so the 0th element is my key
    var key = files.keySelect[0];
    ...
    ...
    // access key with key.path (will be a fakepath)
    fs.readFileSync(key.path);
    // access name with key.originalFilename
    console.log(key.originalFilename);

After a bit of fiddling around It works perfectly. I hope this helps anyone else that faces this problem in the future and thank you very much to those who offered me assistance.

Problem

I am having trouble reading files in different locations (other than the Node project directory). I need to read a private key file (could be located anywhere on the file system) and transfer some yaml/yml files (also could be located anywhere) via sftp. These files are selected in a file input field which is accessed by a post method in my index.js (in Node). The problem is when I try to read the files I get an error that the file doesn't exist, specifically because the directory defaults to the Node project directory. For example: D:/path/to/Node/project D:/this/is/where/the/keyis It will try and read this file: D:/path/to/Node/project/keyis I'm not sure why I only get the filename. I know receiving the entire path is a security risk but I sort of need the path, even if it's not printed at any stage. This is the code for the html form: ``` <form id="file-upload" name="uploadform" method="post" action="/upload" onsubmit="update()"> <input type='text' id='username' class="btn btn-lg btn-default" name='username' placeholder='Enter Username' style="color:#000"><br> <h3>Select Key:</h3><input type='file' id='key-select' name='keySelect'><br> <h3>Select Yaml:</h3><input type="file" id="file-select" name="yamlfiles[]" multiple accept=".yml, .yaml"/><br> <button type="submit" class="btn btn-lg btn-default" id="upload">Upload Data</button> </form> ``` and then in the index.js: ``` router.post('/upload', function(req,res) { // Create a new connection var fs = require('fs'); var Connection = require('ssh2'); var c = new Connection(); // Get the files to be uploaded var files = req.body.yamlfiles; var uname = req.body.username; var key = req.body.keySelect; ... ... c.connect( { host: 'some_host', port: 22, username: uname, privateKey: fs.readFileSync(key) } ); ``` Essentially readFileSync isn't working unless 'key' is in the project path. Is there something that I am missing? The same happens with 'files'.

Original source