Skip to content

Commit c719b0d

Browse files
brophdawg11Gozala
andauthored
feat: add support for application/x-www-form-urlencoded in request.formData() (#60)
Co-authored-by: Irakli Gozalishvili <[email protected]>
1 parent 047f6de commit c719b0d

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

packages/fetch/src/utils/form-data.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {randomBytes} from 'crypto';
22
import { iterateMultipart } from '@web3-storage/multipart-parser';
3+
import { FormData } from '../package.js';
34
import {isBlob} from './is.js';
45

56
const carriage = '\r\n';
@@ -86,8 +87,17 @@ export function getFormDataLength(form, boundary) {
8687
/**
8788
* @param {Body & {headers?:Headers}} source
8889
*/
89-
export const toFormData = async ({ body, headers }) => {
90+
export const toFormData = async (source) => {
91+
let { body, headers } = source;
9092
const contentType = headers?.get('Content-Type') || ''
93+
94+
if (contentType.startsWith('application/x-www-form-urlencoded') && body != null) {
95+
const form = new FormData();
96+
let bodyText = await source.text();
97+
new URLSearchParams(bodyText).forEach((v, k) => form.append(k, v));
98+
return form;
99+
}
100+
91101
const [type, boundary] = contentType.split(/\s*;\s*boundary=/)
92102
if (type === 'multipart/form-data' && boundary != null && body != null) {
93103
const form = new FormData()

packages/fetch/test/main.js

+34
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,25 @@ describe('node-fetch', () => {
15001500
});
15011501
});
15021502

1503+
it('should support URLSearchParams as POST body', () => {
1504+
const params = new URLSearchParams();
1505+
params.set('key1', 'value1');
1506+
params.set('key2', 'value2');
1507+
1508+
const url = `${base}multipart`;
1509+
const options = {
1510+
method: 'POST',
1511+
body: params
1512+
};
1513+
1514+
return fetch(url, options).then(res => res.json()).then(res => {
1515+
expect(res.method).to.equal('POST');
1516+
expect(res.headers['content-type']).to.startWith('application/x-www-form-urlencoded');
1517+
expect(res.body).to.contain('key1=');
1518+
expect(res.body).to.contain('key2=');
1519+
});
1520+
});
1521+
15031522
it('should allow POST request with object body', () => {
15041523
const url = `${base}inspect`;
15051524
// Note that fetch simply calls tostring on an object
@@ -1548,6 +1567,21 @@ describe('node-fetch', () => {
15481567
});
15491568
});
15501569

1570+
it('constructing a Request with URLSearchParams should provide formData()', () => {
1571+
const parameters = new URLSearchParams();
1572+
parameters.append('key', 'value');
1573+
const request = new Request(base, {
1574+
method: 'POST',
1575+
headers: {
1576+
'Content-Type': 'application/x-www-form-urlencoded',
1577+
},
1578+
body: parameters,
1579+
});
1580+
return request.formData().then(formData => {
1581+
expect(formData.get('key')).to.equal('value');
1582+
});
1583+
});
1584+
15511585
it('should allow POST request with URLSearchParams as body', () => {
15521586
const parameters = new URLSearchParams();
15531587
parameters.append('a', '1');

0 commit comments

Comments
 (0)