From 5fba0c21bf33ce4c8258847a7a638db826501e1d Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 13 Apr 2022 12:20:49 -0400 Subject: [PATCH 1/2] fix: support application/x-www-form-urlencoded in request.formData() --- packages/fetch/src/utils/form-data.js | 12 +++++++++- packages/fetch/test/main.js | 34 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/fetch/src/utils/form-data.js b/packages/fetch/src/utils/form-data.js index 24b89748..a22e315a 100644 --- a/packages/fetch/src/utils/form-data.js +++ b/packages/fetch/src/utils/form-data.js @@ -1,5 +1,6 @@ import {randomBytes} from 'crypto'; import { iterateMultipart } from '@web3-storage/multipart-parser'; +import { FormData } from '@web-std/form-data'; import {isBlob} from './is.js'; const carriage = '\r\n'; @@ -86,8 +87,17 @@ export function getFormDataLength(form, boundary) { /** * @param {Body & {headers?:Headers}} source */ -export const toFormData = async ({ body, headers }) => { +export const toFormData = async (source) => { + let { body, headers } = source; const contentType = headers?.get('Content-Type') || '' + + if (contentType.startsWith('application/x-www-form-urlencoded') && body != null) { + const form = new FormData(); + let bodyText = await source.text(); + new URLSearchParams(bodyText).forEach((v, k) => form.append(k, v)); + return form; + } + const [type, boundary] = contentType.split(/\s*;\s*boundary=/) if (type === 'multipart/form-data' && boundary != null && body != null) { const form = new FormData() diff --git a/packages/fetch/test/main.js b/packages/fetch/test/main.js index dedc6b2e..ee4a8a75 100644 --- a/packages/fetch/test/main.js +++ b/packages/fetch/test/main.js @@ -1500,6 +1500,25 @@ describe('node-fetch', () => { }); }); + it('should support URLSearchParams as POST body', () => { + const params = new URLSearchParams(); + params.set('key1', 'value1'); + params.set('key2', 'value2'); + + const url = `${base}multipart`; + const options = { + method: 'POST', + body: params + }; + + return fetch(url, options).then(res => res.json()).then(res => { + expect(res.method).to.equal('POST'); + expect(res.headers['content-type']).to.startWith('application/x-www-form-urlencoded'); + expect(res.body).to.contain('key1='); + expect(res.body).to.contain('key2='); + }); + }); + it('should allow POST request with object body', () => { const url = `${base}inspect`; // Note that fetch simply calls tostring on an object @@ -1548,6 +1567,21 @@ describe('node-fetch', () => { }); }); + it('constructing a Request with URLSearchParams should provide formData()', () => { + const parameters = new URLSearchParams(); + parameters.append('key', 'value'); + const request = new Request(base, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: parameters, + }); + return request.formData().then(formData => { + expect(formData.get('key')).to.equal('value'); + }); + }); + it('should allow POST request with URLSearchParams as body', () => { const parameters = new URLSearchParams(); parameters.append('a', '1'); From a8e99f4b66c8c058cb1934b9e7159b1aeabfa9b6 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Apr 2022 18:56:04 -0700 Subject: [PATCH 2/2] fix: form data import --- packages/fetch/src/utils/form-data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fetch/src/utils/form-data.js b/packages/fetch/src/utils/form-data.js index a22e315a..10d7b2b6 100644 --- a/packages/fetch/src/utils/form-data.js +++ b/packages/fetch/src/utils/form-data.js @@ -1,6 +1,6 @@ import {randomBytes} from 'crypto'; import { iterateMultipart } from '@web3-storage/multipart-parser'; -import { FormData } from '@web-std/form-data'; +import { FormData } from '../package.js'; import {isBlob} from './is.js'; const carriage = '\r\n';