Home > Mobile >  Sending Multipart form using string body
Sending Multipart form using string body

Time:12-22

I have seen almost all answers in relation to this suggest to use some variant of FormData within nodejs to build a multipart form.

I wish to achieve the same without using the FormData library, but instead just using request headers and a string for the request body.

Only one answer hints at how this can be achieved, but the solution uses a stringify function on the string payload so I am not sure how the correct stringified body should look like.

Regardless, I have gotten this far;

import { RequestOptions } from "http"

const path: 'url/'
const method: 'POST'

const body = `--BOUNDARY
\nContent-Disposition: form-data; name="file"; filename="test.txt"
\nContent-Type: text/plain
\nThis is the content of the file
\n--BOUNDARY
\nContent-Disposition: form-data; name="form-field-one"
\nexample1
\n--BOUNDARY
\nContent-Disposition: form-data; name="form-field-two"
\nexample2
\n--BOUNDARY--`

const headers = {
  'content-type': 'multipart/form-data; boundary=BOUNDARY',
  'content-length': String(Buffer.byteLength(body))
}

const options = {
  path,
  method,
  headers,
  body
}

const response = await execute(options)

I cannot create a fully minimal reproduction as I am not permitted to post the execute function contents, but I can describe the function signature I need to use (which is why I need to use this string approach).

For what its worth, i think the function is simply using the basic builtin nodejs http library.

import { RequestOptions } from "http"

const execute = async (options: RequestOptions): Promise<any> => { ... }

I get an error using this, but the error is not helpful at all due to the internals of the function.

Regardless, I believe it should be possible to replicate sending a multi-part form (with file and form fields) using just the body and headers of a POST request without an additional library to transform the data of the body.

My string is a modified output from a successful Postman request multipart form request.

Can someone point out what I am doing incorrectly?

CodePudding user response:

Several points:

  • Every line in your `...` already ends with a newline, but the next starts with \n, which contributes another newline, leading to an unwanted blank line.
  • You do need a blank line between the headers and content.
  • Lines must end with CRLF, so you must add a \r as the last character on each line.

Try this:

const body = `--BOUNDARY\r
Content-Disposition: form-data; name="file"; filename="test.txt"\r
Content-Type: text/plain\r
\r
This is the content of the file\r
--BOUNDARY\r
Content-Disposition: form-data; name="form-field-one"\r
\r
example1\r
--BOUNDARY\r
Content-Disposition: form-data; name="form-field-two"\r
\r
example2\r
--BOUNDARY--`

CodePudding user response:

Certainly! It looks like you're trying to build a multipart form request body manually as a string. There are a few issues with the string you've provided:

The string is missing the final newline before the final --BOUNDARY-- boundary marker. The Content-Type header for the file should specify the type of the file being uploaded. In this case, you've specified text/plain, but you'll want to use the appropriate MIME type for the file you're trying to upload. The Content-Disposition headers for the form fields should have a value parameter, like this:

Content-Disposition: form-data; name="form-field-one"; value="example1" Here's an example of how the body string should look like: const body = `--BOUNDARY Content-Disposition: form-data; name="file"; filename="test.txt" Content-Type: text/plain

This is the content of the file --BOUNDARY Content-Disposition: form-data; name="form-field-one"; value="example1"

--BOUNDARY Content-Disposition: form-data; name="form-field-two"; value="example2"

--BOUNDARY-- `;

Note that each part of the form is separated by a boundary marker, and each part should have a blank line after the headers.

I hope this helps! Let me know if you have any questions.

CodePudding user response:

It is possible to create a multipart form POST request using just the body and headers of the request. However, it is a bit more involved than simply setting the Content-Type header to multipart/form-data and including the data in the body of the request.

Here's a step-by-step guide on how you can create a multipart form POST request using just the body and headers:

  1. Choose a boundary string that will be used to separate the different parts of the request. The boundary should be a unique string that does not appear in the data that you are sending. In your code, you have chosen BOUNDARY as the boundary string.

  2. Set the Content-Type header to multipart/form-data; boundary=BOUNDARY, where BOUNDARY is the boundary string you chose in step 1.

  3. Begin the body of the request with the boundary string, followed by a newline character. For example:

    --BOUNDARY\n

  4. For each field in the form, add a Content-Disposition header and the field value. The Content-Disposition header should include the name of the field, as well as any other necessary information (such as filename for file fields). For example:

Content-Disposition: form-data; name="form-field-one"\n
example1\n

  1. For file fields, include the Content-Type header as well as the contents of the file. For example

Content-Disposition: form-data; name="file"; filename="test.txt"\n
Content-Type: text/plain\n
This is the content of the file\n

  1. After each field, include the boundary string followed by a newline character. For example:

--BOUNDARY\n

  1. After the last field, include the boundary string followed by -- to indicate the end of the request.

So, the complete body of the request should look something like this:

--BOUNDARY
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
This is the content of the file
--BOUNDARY
Content-Disposition: form-data; name="form-field-one"
example1
--BOUNDARY
Content-Disposition: form-data; name="form-field-two"
example2
--BOUNDARY--

  • Related