Home > database >  Uploading File to FTP Server with node.js requires full directory path to file which isn't avai
Uploading File to FTP Server with node.js requires full directory path to file which isn't avai

Time:06-24

I am new to js/reactjs/nodejs and I am implementing a feature to allow a user to choose a file manually and upload it to a test local ftp server (in directory /test). The issue i am having is that the ftp.upload function takes a String for the full path of the file being uploaded, but I am not explicitly giving the path because the file is chosen via a "Browse files" button.

It works perfectly if I test without ftp (locally), but I can't seem to upload the file from the request onto a FTP-Server. If I add a full path to the file which I want to upload, it seems to work but that ruins the purpose of choosing a file to upload and uploading after clicking on Upload

This is the server.js

const express = require("express");
const fileUpload = require("express-fileupload");
const app = express();
var EasyFtp = require("easy-ftp");
var ftp = new EasyFtp();

app.use(fileUpload());

var config = {
  host: "127.0.0.1",
  type: "FTP",
  port: "",
  username: "admin",
  password: "",
};

ftp.connect(config);

app.post("/upload", (req, res) => {
  console.log(req.files);
  if (req.files === null) {
    return res.status(400).json({ msg: "No file was uploaded" }); //no file uploaded
  }
  const file = req.files.file;

  ftp.upload(file, "/test", function (err) {
    if (err) {
      console.log(err);
      return res.status(500).send(err);
    } else {
      console.log("finished:", res);
      res.json({ fileName: file.name, filePath: `/upload/${file.name}` });
    }
  });

  //   res.json({ fileName: file.name, filePath: `/uploads/${file.name}` });
});
  ftp.mv(
`/test/(${
  (file.tempFilePath.split("/").at(-1),
  file.name,
  function (err, newPath) {})
})`
  );

ftp.close();
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`server started on port ${PORT}`));

This is the FileUpload file

import React, { Fragment, useState } from "react";
import axios from "axios";
import Message from "./Message";
import Progress from "./Progress";

const FileUpload = () => {
  //actual file and filename should go into state because the label "Choose File" needs to be replaced with the actual filename

  const [files, setFile] = useState("");
  const [filename, setFilename] = useState("Choose File...");
  const [uploadedFiles, setUploadedFiles] = useState({});
  const [message, setMessage] = useState("");
  const [uploadPercent, setUploadPercent] = useState(0);

  const onChange = (e) => {
    setFile(e.target.files[0]);
    let x = [];
    for (let file of e.target.files) {
      x.push(file.name);
    }
    setFilename(x);
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    //add the file to form data
    const formData = new FormData();
    formData.append("file", files);
    try {
      const response = await axios.post("/upload", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },

        //progress bar for upload
        onUploadProgress: (progressEvent) => {
          setUploadPercent(
            parseInt(
              //get rid of progress bar after 10 seconds of finished upload
              Math.round((progressEvent.loaded * 100) / progressEvent.total)
            )
          );
          setTimeout(() => setUploadPercent(0), 1000);
        },
        //clear loaded percentage bar
      });
      const { fileName, filePath } = response.data;

      setUploadedFiles({ fileName, filePath });
      setMessage("File uploaded successfully");
    } catch (error) {
      if (error.response.status === 500) {
        setMessage("There was a problem with the server, please try again.");
      } else {
        setMessage(error.response.data.msg);
      }
    }
  };

  return (
    <Fragment>
      {message ? <Message msg={message} /> : null}
      <form onSubmit={onSubmit}>
        <div className="custom-file">
          <input
            type="file"
            className="custom-file-input"
            id="customFile"
            onChange={onChange}
            multiple
          />
          <label className="custom-file-label" htmlFor="customFile">
            {filename}
          </label>
        </div>
        <Progress percentage={uploadPercent} />
        <input
          type="submit"
          value="Upload"
          className="btn btn-primary btn-block mt-4"
        />
      </form>
    </Fragment>
  );
};

export default FileUpload;

Is there any way to correct this? What am I missing? If more code snippets are required please let me know!

UPDATE!!


ftp.mv not doing anything

app.post("/upload", (req, res) => {
  console.log(req.files);
  if (req.files === null) {
    return res.status(400).json({ msg: "No file was uploaded" }); //error message if no file was uploaded
  }

  const file = req.files.file;
  const tempFileName = file.tempFilePath.split("/").at(-1);

  ftp.upload(file.tempFilePath, "/test", function (err) {
    if (err) {
      console.log(err);
      return res.status(500).send(err);
    } else {
      console.log("finished:", res);
      res.json({
        fileName: file.name,
        filePath: `/uploads/${file.name}`,
      });
    }
  });
  ftp.mv(`/test/${tempFileName}`, "abc", function (err, newPath) {});
  ftp.close();
});

CodePudding user response:

You are sending a file to the server, you need to save it momentarily and upload it from there, start by changing your fileUpload configuration to this:

    app.use(fileUpload({
      useTempFiles : true,
      tempFileDir : '/tmp/'
    }));

Then you can upload the file by accessing its temporary file path:

app.post("/upload", (req, res) => {
  console.log(req.files);
  if (req.files === null) {
    return res.status(400).json({ msg: "No file was uploaded" }); //no file uploaded
  }
  const file = req.files.file;
  // here we access the temporary file path
  ftp.upload(file.tempFilePath, "/test", function (err) {
    if (err) {
      console.log(err);
      return res.status(500).send(err);
    } else {
      console.log("finished:", res);
      res.json({ fileName: file.name, filePath: `/upload/${file.name}` });
    }
    ftp.close();
  });

 });
});

    
  • Related