Home > Enterprise >  How do I upload a file to the server in Javascript?
How do I upload a file to the server in Javascript?

Time:10-14

Apparently this isn't as straight forward as I thought. Here is what I'm doing:

I'm collecting the FileList to state like so...

const [formValues, setFormValues] = useState({
    image: null
})

<input type="file" name="image" onChange={e => setFormValues({...formValues, image: e.target.files})}/>

I'm then appending the FileList to FormData like so...

const formData = new FormData()
formData.append('image', formValues.image)

I send the post request via Axios like so...

try {
    const response = axios.post('http://localhost:4000/uploadShow', formData)
    console.log(response)
} catch (e) {
    console.log(e)
}

Checking the contents of the file from the server like this...

console.log(req.body)
console.log(`IMAGE FILE:\n${JSON.stringify(req.body.image[0])}`)

Results in this...

[Object: null prototype] {
  Image: '[object FileList]'
}
IMAGE FILE:
"["

Nothing seems to be going wrong in the devtools Network tab. 200 response code. image does not show the contents of the FileList. Logging the JSON string of file[0] gives me an empty array that isn't even closed off. I have no idea what to make of this.

Why is the file itself not making it to the backend, even though the FilesList apparently is? Can someone please tell me what I'm doing wrong here? I'm happy to provide any additional details you may need. Thanks in advance.

CodePudding user response:

It's unclear what you're trying to do with your setFormValues() function as you don't show the whole context here. But, what you should do is at the point in time when you want to do the upload, you just go get the file data directly from the form.

Here are three ways to do it, all of which I've tested and work:

Let Browser Upload the Form

<form id="myForm" action="/upload" enctype="multipart/form-data" method="post">
    <label  for="file">Upload Your File</label>
    <input id="file" accept="image/jpeg,image/gif,image/png,application/pdf,image/x-eps" name="fileToUpload" type="file" />
    <br><button  name="submit" type="submit">
        Upload File
    </button>
</form>

Create FormData object from the Entire Form, Upload with Axios

<form id="myForm" action="/upload" enctype="multipart/form-data" method="post">
    <label  for="file">Upload Your File</label>
    <input id="file" accept="image/jpeg,image/gif,image/png,application/pdf,image/x-eps" name="fileToUpload" type="file" />
    <br><button id="axiosButton1"  name="submitAxios">
        Upload File via Axios whole FormData
    </button>
</form>
<script>
    // button1, create FormData from the whole form
    document.getElementById("axiosButton1").addEventListener("click", e => {
        e.preventDefault();
        const formData = new FormData(document.getElementById("myForm"))
        axios.post("/upload", formData).then(result => {
            console.log(result);
            alert("upload complete");
        }).catch(err => {
            console.log(err);
            alert("upload error");
        })
    });

</script>

Create FormData object manually and just append the file object to it, Upload with Axios

<form id="myForm" action="/upload" enctype="multipart/form-data" method="post">
    <label  for="file">Upload Your File</label>
    <input id="file" accept="image/jpeg,image/gif,image/png,application/pdf,image/x-eps" name="fileToUpload" type="file" />
    <br><button id="axiosButton2"  name="submitAxios">
        Upload File via Axios created FormData
    </button>
</form>
<script>
    // button2, manually created FormData with just files added to it
    document.getElementById("axiosButton2").addEventListener("click", e => {
        console.log("axiosButton2");
        e.preventDefault();
        const fileItem = document.getElementById("file");
        const formData = new FormData();
        formData.append("fileToUpload", fileItem.files[0]);
        axios.post("/upload", formData).then(result => {
            console.log(result);
            alert("upload complete xxx");
        }).catch(err => {
            console.log(err);
            alert("upload error");
        })
    });
</script>

Back End

And, all three of these options work with this backend code where the uploaded file is deposited into the uploads/ directory:

import express from 'express';
import multer from 'multer';
const upload = multer({ dest: 'uploads/' });
import path from 'path';

const app = express();

app.get("/", (req, res) => {
    res.sendFile(path.resolve("index.html"));
});

app.post("/upload", upload.single('fileToUpload'), (req, res) => {
    console.log(req.file);
    res.send("upload complete");
});

app.listen(80);

CodePudding user response:

I would suggest using websockets instead. Here is a good tutorial on it. It works quite fast with node js.

  • Related