Skip to content

Commit 9dfe934

Browse files
authored
feat: Request.postDataJSON (#2368)
1 parent e168fdd commit 9dfe934

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

docs/api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,6 +3499,7 @@ If request gets a 'redirect' response, the request is successfully finished with
34993499
- [request.isNavigationRequest()](#requestisnavigationrequest)
35003500
- [request.method()](#requestmethod)
35013501
- [request.postData()](#requestpostdata)
3502+
- [request.postDataJSON()](#requestpostdatajson)
35023503
- [request.redirectedFrom()](#requestredirectedfrom)
35033504
- [request.redirectedTo()](#requestredirectedto)
35043505
- [request.resourceType()](#requestresourcetype)
@@ -3538,6 +3539,11 @@ Whether this request is driving frame's navigation.
35383539
#### request.postData()
35393540
- returns: <?[string]> Request's post body, if any.
35403541

3542+
#### request.postDataJSON()
3543+
- returns: <?[Object]> Parsed request's body for `form-urlencoded` and JSON as a fallback if any.
3544+
3545+
When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned. Otherwise it will be parsed as JSON.
3546+
35413547
#### request.redirectedFrom()
35423548
- returns: <?[Request]> Request that was redirected by the server to this one, if any.
35433549

src/network.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import * as util from 'util';
2020
import * as frames from './frames';
2121
import { assert, helper } from './helper';
2222
import { Page } from './page';
23+
import { URLSearchParams } from 'url';
2324

2425
export type NetworkCookie = {
2526
name: string,
@@ -153,6 +154,25 @@ export class Request {
153154
return this._postData;
154155
}
155156

157+
postDataJSON(): Object | null {
158+
if (!this._postData)
159+
return null;
160+
161+
const contentType = this.headers()['content-type'];
162+
if (!contentType)
163+
return null;
164+
165+
if (contentType === 'application/x-www-form-urlencoded') {
166+
const entries: Record<string, string> = {};
167+
const parsed = new URLSearchParams(this._postData);
168+
for (const [k, v] of parsed.entries())
169+
entries[k] = v;
170+
return entries;
171+
}
172+
173+
return JSON.parse(this._postData);
174+
}
175+
156176
headers(): {[key: string]: string} {
157177
return { ...this._headers };
158178
}

test/network.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,34 @@ describe('Request.postData', function() {
140140
});
141141
});
142142

143+
describe('Request.postDataJSON', function () {
144+
it('should parse the JSON payload', async ({ page, server }) => {
145+
await page.goto(server.EMPTY_PAGE);
146+
server.setRoute('/post', (req, res) => res.end());
147+
let request = null;
148+
page.on('request', r => request = r);
149+
await page.evaluate(() => fetch('./post', { method: 'POST', body: JSON.stringify({ foo: 'bar' }) }));
150+
expect(request).toBeTruthy();
151+
expect(request.postDataJSON()).toEqual({ "foo": "bar" });
152+
});
153+
154+
it('should parse the data if content-type is application/x-www-form-urlencoded', async({page, server}) => {
155+
await page.goto(server.EMPTY_PAGE);
156+
server.setRoute('/post', (req, res) => res.end());
157+
let request = null;
158+
page.on('request', r => request = r);
159+
await page.setContent(`<form method='POST' action='/post'><input type='text' name='foo' value='bar'><input type='number' name='baz' value='123'><input type='submit'></form>`);
160+
await page.click('input[type=submit]');
161+
expect(request).toBeTruthy();
162+
expect(request.postDataJSON()).toEqual({'foo':'bar','baz':'123'});
163+
})
164+
165+
it('should be |undefined| when there is no post data', async ({ page, server }) => {
166+
const response = await page.goto(server.EMPTY_PAGE);
167+
expect(response.request().postDataJSON()).toBe(null);
168+
});
169+
});
170+
143171
describe('Response.text', function() {
144172
it('should work', async({page, server}) => {
145173
const response = await page.goto(server.PREFIX + '/simple.json');

0 commit comments

Comments
 (0)