johanleroux's avatar

NodeJS File Upload

Hi Everyone,

I've been stuck on this problem for a couple of days now and honestly feel like a moron for not figuring it out.

Basically I have a Electron app running with Vue. I want to send local files of app to my remote Laravel server, easy right? welp I thought so too.

I have a FormData object that I build up with random data, except for the entry which is a file that is a stream from Node's filesystem. I then send this using the Axios global variable this.$http, when sending this the file gets encapsulated as a string. Any ideas?

Upload Script:

syncFile (customer, file) {
        let endpoint = this.url + 'customers/' + customer + '/identification'

        let form = new FormData()
        form.append('foo', 'bar')
        form.append('bar', 'baz')
        form.append('baz', 'foo')
        form.append('file', fs.createReadStream(file.filePath))

        this.$http.post(endpoint, form, { headers: { 'Content-Type': `multipart/form-data; boundary=${form._boundary}`, 'Authorization': 'token' } }
        )
          .then(response => console.log(response))
          .catch(error => console.log(error.response))
      },

Payload:

'foo': 'bar',
'bar': 'baz',
'baz:' 'foo',
'file': '[object Object]'

Any help will really be appreciated. mrunknown

0 likes
1 reply
johanleroux's avatar
johanleroux
OP
Best Answer
Level 14

After many more hours and reading I have a solution, but from my research I figured out a lot of people struggle with this and Axios and Form Data doesn't have 100% compatibility

const concat = require("concat-stream")
const fd = new FormData()

fd.append("hello", "world")
fd.append("file", fs.createReadStream(file))
fd.pipe(concat(data => {
  axios.post("/hello", data, {
    headers: fd.getHeaders()
  })
}))

If you are going to use binary files (image etc) like most people then your need to encode the concat stream to binary buffer:

fd.pipe(concat({encoding: 'buffer'}, data => {

Please or to participate in this conversation.