FormData with file is not setting boundary when running in jsdom env
edenhermelin opened this issue · comments
Describe the bug
Hi,
when trying to send a FormData request that includes a file on a test that is using jsdom
,
seems like the request is not adding the content-length properly (as happens automatically on the browser/Node.js)
Reproduction
System Info
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 18.18.0 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 10.2.3 - /usr/local/bin/npm
pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
@vitest/ui: latest => 1.6.0
vite: latest => 5.2.11
vitest: latest => 1.6.0
Used Package Manager
pnpm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
on the browser/Node.js
fetch
is provided by Node.js, but FormData
is provided by jsdom, so fetch doesn't know how to handle it. This is out of scope of Vitest as we don't control how environments implement their API. To make this work, you can reassign FormData
to Node.js one, patch global fetch or wait for JSDOM to implement their own fetch
method.
on the browser/Node.js
fetch
is provided by Node.js, butFormData
is provided by jsdom, so fetch doesn't know how to handle it. This is out of scope of Vitest as we don't control how environments implement their API. To make this work, you can reassignFormData
to Node.js one, patch global fetch or wait for JSDOM to implement their ownfetch
method.
Ok, thanks.
Is there a similar example for one of the workaround methods?
Technically overwriting globals back to nodejs is possible, but I feel the purpose of jsdom environment is questionable at this point.
https://stackblitz.com/edit/vitest-dev-vitest-amqvxh?file=test%2Fbasic.test.ts
// this works because jsdom doesn't provide `Request` and it's coming from NodeJs/undici
async function restoreNodeGlobals() {
const nodeGlobals: any = {};
{
const request = new Request("https://test.local", {
method: "POST",
headers: {
"content-type": "application/x-www-form-urlencoded",
},
});
const formData = await request.formData();
nodeGlobals.FormData = formData.constructor;
}
{
const request = new Request("https://test.local", {
method: "POST",
});
const blob = await request.blob();
nodeGlobals.Blob = blob.constructor;
}
Object.assign(globalThis, nodeGlobals);
}
FYI, the similar issue has been discussed in #4043