2

I am trying to upload a file from my computer using native https.request from node.js. My code look like this:

let query = require('https').request({
  hostname: 'somehost.com',
  path: '/path/to/upload',
  headers: {'Content-Type': 'multipart/form-data'},
  method: 'POST'
}, (res) => {
  let data = '';
  res.on("data", (chunk) => {
    data += chunk.toString('utf8');
  });
  res.on('end', () => {
    console.log("data");
  })
});
query.on("error", (e) => {
  console.error(e);
});
query.write(Buffer[
  {key1: 1, file: require("fs").createReadStream("/path/to/file.txt")}
]);      // I don't know how to put here
query.end();

I don't get any response from host, the file failed to upload. How can I do this?

1 Answer 1

2
+50

When uploading multipart/form-data, the Content-Type header must include a boundary, in order to indicate where each "part" lives within the posted data. In order to set the boundary for The Multipart Content-Type, you can use the form-data package from NPM. You could set the header/boundary manually, but the form-data package will handle this for you and free you from having to worry about the details, etc.

In order to use form-data in your example, you will need to do the following:

  1. Create a new FormData object and append the relevant parts:

    let formData = new require('form-data')();
    formData.append('key1', 1);
    formData.append('file', require("fs").createReadStream("/path/to/file.txt"));
    
  2. Use the getHeaders function to build the correct HTTP headers:

    require('https').request({
        headers: formData.getHeaders(),
        // ...
    }
    
  3. Use pipe in order to allow form-data to process your data and send it to the server:

    formData.pipe(query);
    

    With this change, you no longer need your calls to query.write or query.end - the call to pipe takes care of that.

For completeness, here's the final code with the changes I described:

let formData = new require('form-data')();
formData.append('key1', 1);
formData.append('file', require("fs").createReadStream("/path/to/file.txt"));

let query = require('https').request({
    hostname: 'somehost.com',
    path: '/path/to/upload',
    method: 'POST',
    headers: formData.getHeaders()
}, (res) => {
    let data = '';
    res.on("data", (chunk) => {
        data += chunk.toString('utf8');
    });
    res.on('end', () => {
        console.log(data);
    })
});

query.on("error", (e) => {
    console.error(e);
});

formData.pipe(query);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.