diff --git a/lib/web/fetch/body.js b/lib/web/fetch/body.js index b092b3c83db..80ef027b800 100644 --- a/lib/web/fetch/body.js +++ b/lib/web/fetch/body.js @@ -109,7 +109,7 @@ function extractBody (object, keepalive = false) { // Set source to a copy of the bytes held by object. source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) - } else if (webidl.is.FormData(object)) { + } else if (webidl.is.FormData(object) || (globalThis.FormData && object instanceof FormData)) { const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` const prefix = `--${boundary}\r\nContent-Disposition: form-data` diff --git a/lib/web/fetch/formdata.js b/lib/web/fetch/formdata.js index 8020a26e116..0f7bb766602 100644 --- a/lib/web/fetch/formdata.js +++ b/lib/web/fetch/formdata.js @@ -258,6 +258,13 @@ function makeEntry (name, value, filename) { return { name, value } } -webidl.is.FormData = webidl.util.MakeTypeAssertion(FormData) +const _isFormData = webidl.util.MakeTypeAssertion(FormData) +webidl.is.FormData = function (V) { + // This is a compatibility fix to support the FormData instance that is shipped in Node.js + if (globalThis.FormData && V instanceof globalThis.FormData) { + return true + } + return _isFormData(V) +} module.exports = { FormData, makeEntry, setFormDataState } diff --git a/test/fetch/client-fetch.js b/test/fetch/client-fetch.js index 3003021390b..af263c2eedf 100644 --- a/test/fetch/client-fetch.js +++ b/test/fetch/client-fetch.js @@ -709,3 +709,25 @@ test('Receiving non-Latin1 headers', async (t) => { assert.deepStrictEqual(cdHeaders, ContentDisposition) assert.deepStrictEqual(lengths, [30, 34, 94, 104, 90]) }) + +test('post globalThis.FormData with Blob', (t, done) => { + const { ok } = tspl(t, { plan: 1 }) + + // We use the FormData that is shipped in Node.js + const body = new globalThis.FormData() + body.append('field1', new Blob(['asd1'])) + + const server = createServer((req, res) => { + req.pipe(res) + }) + t.after(closeServerAsPromise(server)) + + server.listen(0, async () => { + const res = await fetch(`http://localhost:${server.address().port}`, { + method: 'PUT', + body + }) + ok(/asd1/.test(await res.text())) + done() + }) +})