FormData body is parsed as "[object FormData]" string
See original GitHub issueDescribe the bug
When sending a POST request with a FormData
body, the req.body
contains a string "[object FormData]"
and I can’t get the data that was sent.
Environment
msw: 0.26.2
nodejs: 14.15.4
npm: 6.14.11
Browser version is not relevant as I’m using msw in Jest tests context. Jest version is 26.6.3.
To Reproduce
- Send a request from the application with POST method and a
FormData
object as the body
const form = document.querySelector(".my-form")
fetch("http://localhost/user/register", {
method: "POST",
body: new FormData(form)
})
- Implement a POST handler in msw and log
req.body
:
import { rest } from "msw"
export const handlers = [
rest.post("/user/register", (req, res, ctx) => {
console.log(req.body, typeof req.body)
return res(ctx.status(200))
}),
]
- See that you get
[object FormData] string
as theconsole.log
result
Expected behavior
I expected req.body
to be an object like it is in the browser.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:7 (5 by maintainers)
Top Results From Across the Web
Using FormData Objects - Web APIs | MDN
The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest . It is primarily intended for use in...
Read more >Parse FormData object in nest controller - json - Stack Overflow
This will allow for the parsing of multipart/form-data requests. In your axios call, remove the brackets around bodyContent so it becomes data: ...
Read more >FormData - The Modern JavaScript Tutorial
The special thing about FormData is that network methods, such as fetch , can accept a FormData object as a body. It's encoded...
Read more >Using FormData Objects Effectively - YouTube
This video explains how you can use a FormData object to quickly and easily grab all the data from any form and send...
Read more >Convert Form Data to JavaScript Object - Stack Abuse
Even though it may seem like we've created an empty object, that is not the case. That FormData object has a key-value pair...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Coming back to you with my findings.
FormData
in a browserAs mentioned previously, I’ve got a basic in-browser test working well with constructing
FormData
and passing it as a request’s body. MSW provides you the request body as serializedFormData
(done byfetch
), so you could access it inreq.body[fieldName]
.FormData
in DOM-like environmentIn a DOM-like environment (i.e. JSDOM), you need to use a
FormData
polyfill. Jest comes with one, but bear in mind that FormData polyfills are not always compatible with fetch polyfills you decide to use. For instance, this is invalid:It is when you use an incompatible polyfill for your request client you get the
[object FormData]
text as your request body. MSW receives whichever request body your client produces, there’s no parsing logic whatsoever (one of the benefits of Service Workers in a browser and native modules monkey-patching in NodeJS).FormData
in NodeJSUnless you use a polyfill (i.e.
form-data-node
), there is noFormData
in NodeJS. This makes sense, as you don’t have DOM and thus forms to construct that data. Polyfills use a Map-like API to allow you to append/set form fields on the polyfilledFormData
instance.How to get the proper data in the request?
If you use the right
FormData
polyfill for your request issuing library you’ll get the serialized form data in the request body:I understand this is not ideal, as you’re detaching your test from DOM/JSDOM to act as the source for data. I’d also suggest experimenting with fetch/FormData polyfills to find a suitable combination. Alternatively, consider moving such a test to an actual browser as that would give you the most confidence and you wouldn’t have to deal with polyfills. You can use tools like Cypress for that, or in case you feel like it’s an overkill to pull in a new testing framework you may consider tiny utilities like
page-with
that still run in an actual browser.Thanks @kettanaito for investigating this.
The only difference I see is that you are using
setupWorker
, so it means you are in a browser context if I’m not mistaken. In my case, I usesetupServer
because I am in a Jest tests (so node js) context.The tests I did in the browser showed that it works well in this environment. But in node environement
req.body
is a string.