msw
msw copied to clipboard
fix(multipart/form-data): Include form data in the request payload when making a proxy request with ctx.fetch(req)
Fixes https://github.com/mswjs/msw/issues/1158
When making a FormData request, the browser adds the content-type header automatically and adds a boundary e.g.
"content-type": multipart/form-data; boundary=----WebKitFormBoundarygyGKnRF8C9LT0BhB"
.
const formData = new FormData();
formData.append("key", "value");
fetch("/post", { method: "POST", body: formData });
When this request is intercepted and proxied
export const handlers = [
rest.post("/post", async (req, res, ctx) => {
console.log("msw body:", req.body);
const proxy = await ctx.fetch(req);
return res(
ctx.status(proxy.status),
ctx.body(await proxy.text())
);
}),
];
and we are creating a new request in mockServiceWorker.js
,
const originalRequest = new Request(requestClone, {
headers: new Headers(cleanRequestHeaders),
})
then cleanRequestHeaders
will have the property "content-type": multipart/form-data; boundary=----WebKitFormBoundarygyGKnRF8C9LT0BhB"
. The browser treats this as a user-provided header and does not add a new boundary value. This will break the body and no payload will be send. If we delete the content-type header, the browser will automatically re-add it with a new boundary value and the form data is included in the payload.
Solution found here: https://community.cloudflare.com/t/cannot-seem-to-send-multipart-form-data/163491/2
Notice the new boundary value:
This pull request is automatically built and testable in CodeSandbox.
To see build info of the built libraries, click here or the icon next to each commit SHA.
Latest deployment of this branch, based on commit 3c887e492dab7cec1f3aca5898a4429b4f626678:
Sandbox | Source |
---|---|
MSW React | Configuration |
Hey, @MartinJaskulla. Thanks for opening this!
This is interesting. As I understand, the issue happens only when proxying requests with ctx.fetch
. What do you think if we add this headers logic to that very function instead of the worker script?
Changes to the worker script are always breaking changes, as developers would have to update those on their machines to guarantee MSW works as expected (even if they're using an automatic update route). I'd much prefer for this to be tackled in the underlying API like ctx.fetch
, especially if that's where the problem occurs.
Do you see any implications of moving this change to ctx.fetch
?
Makes sense. ctx.fetch
seems like a much better place for this check. Also easier to unit test.
Will take a look tomorrow evening.
Sounds fantastic! Thank you so much.