mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
fix(rewrite): copy body from the request (#11182)
* fix(rewrite): copy body from the request * wip * chore: copy body without using it * chore: remove new file
This commit is contained in:
parent
b24838f798
commit
40b0b4d1e4
5 changed files with 80 additions and 3 deletions
5
.changeset/swift-phones-rhyme.md
Normal file
5
.changeset/swift-phones-rhyme.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes an issue where `Astro.rewrite` wasn't carrying over the body of a `Request` in on-demand pages.
|
|
@ -224,7 +224,7 @@ export class RenderContext {
|
|||
if (reroutePayload instanceof Request) {
|
||||
this.request = reroutePayload;
|
||||
} else {
|
||||
this.request = new Request(
|
||||
this.request = this.#copyRequest(
|
||||
new URL(routeData.pathname ?? routeData.route, this.url.origin),
|
||||
this.request
|
||||
);
|
||||
|
@ -416,7 +416,7 @@ export class RenderContext {
|
|||
if (reroutePayload instanceof Request) {
|
||||
this.request = reroutePayload;
|
||||
} else {
|
||||
this.request = new Request(
|
||||
this.request = this.#copyRequest(
|
||||
new URL(routeData.pathname ?? routeData.route, this.url.origin),
|
||||
this.request
|
||||
);
|
||||
|
@ -533,4 +533,34 @@ export class RenderContext {
|
|||
if (!i18n) return;
|
||||
return (this.#preferredLocaleList ??= computePreferredLocaleList(request, i18n.locales));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function that creates a new `Request` with a new URL from an old `Request`.
|
||||
*
|
||||
* @param newUrl The new `URL`
|
||||
* @param oldRequest The old `Request`
|
||||
*/
|
||||
#copyRequest(newUrl: URL, oldRequest: Request): Request {
|
||||
return new Request(newUrl, {
|
||||
method: oldRequest.method,
|
||||
headers: oldRequest.headers,
|
||||
body: oldRequest.body,
|
||||
referrer: oldRequest.referrer,
|
||||
referrerPolicy: oldRequest.referrerPolicy,
|
||||
mode: oldRequest.mode,
|
||||
credentials: oldRequest.credentials,
|
||||
cache: oldRequest.cache,
|
||||
redirect: oldRequest.redirect,
|
||||
integrity: oldRequest.integrity,
|
||||
signal: oldRequest.signal,
|
||||
keepalive: oldRequest.keepalive,
|
||||
// https://fetch.spec.whatwg.org/#dom-request-duplex
|
||||
// @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
|
||||
duplex: "half"
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
8
packages/astro/test/fixtures/reroute/src/pages/post/post-a.astro
vendored
Normal file
8
packages/astro/test/fixtures/reroute/src/pages/post/post-a.astro
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
let email = ''
|
||||
return Astro.rewrite('/post/post-b')
|
||||
---
|
||||
|
||||
<h1>Post A</h1>
|
||||
|
||||
<h2>{email}</h2>
|
15
packages/astro/test/fixtures/reroute/src/pages/post/post-b.astro
vendored
Normal file
15
packages/astro/test/fixtures/reroute/src/pages/post/post-b.astro
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
let email = ''
|
||||
if (Astro.request.method === 'POST') {
|
||||
try {
|
||||
const data = await Astro.request.json();
|
||||
email = data.email?.toString().trim();
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
<h1>Post B</h1>
|
||||
|
||||
<h2>{email}</h2>
|
|
@ -61,6 +61,7 @@ describe('Dev reroute', () => {
|
|||
|
||||
assert.equal($('h1').text(), '404: Not found');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Build reroute', () => {
|
||||
|
@ -112,7 +113,7 @@ describe('Build reroute', () => {
|
|||
|
||||
it('should render the 404 built-in page', async () => {
|
||||
try {
|
||||
const html = await fixture.readFile('/spread/oops/index.html');
|
||||
await fixture.readFile('/spread/oops/index.html');
|
||||
assert.fail('Not found');
|
||||
} catch {
|
||||
assert.ok;
|
||||
|
@ -187,6 +188,24 @@ describe('SSR reroute', () => {
|
|||
const html = await response.text();
|
||||
assert.equal(html, 'Not found');
|
||||
});
|
||||
|
||||
it('should pass the POST data from one page to another', async () => {
|
||||
const request = new Request('http://example.com/post/post-a', {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
email: "example@example.com",
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
});
|
||||
const response = await app.render(request);
|
||||
const html = await response.text();
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
assert.equal($('h1').text(), 'Post B');
|
||||
assert.match($('h2').text(), /example@example.com/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Middleware', () => {
|
||||
|
|
Loading…
Reference in a new issue