Skip to content

Commit 1f2b69c

Browse files
fix: hydration for null body http status response (#13985)
* fix: hydration for 204 response * Added null status body http codes * add test * simplify * prettier --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 6897acb commit 1f2b69c

File tree

8 files changed

+35
-3
lines changed

8 files changed

+35
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const NULL_BODY_STATUS = [101, 103, 204, 205, 304];

packages/kit/src/runtime/server/page/load_data.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { with_request_store, merge_tracing } from '@sveltejs/kit/internal/server
66
import { record_span } from '../../telemetry/record_span.js';
77
import { clarify_devalue_error, get_node_type } from '../utils.js';
88
import { base64_encode, text_decoder } from '../../utils.js';
9+
import { NULL_BODY_STATUS } from '../constants.js';
910

1011
/**
1112
* Calls the user's server `load` function.
@@ -345,7 +346,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
345346
const proxy = new Proxy(response, {
346347
get(response, key, _receiver) {
347348
/**
348-
* @param {string} body
349+
* @param {string | undefined} body
349350
* @param {boolean} is_b64
350351
*/
351352
async function push_fetched(body, is_b64) {
@@ -427,6 +428,11 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
427428
async function text() {
428429
const body = await response.text();
429430

431+
if (body === '' && NULL_BODY_STATUS.includes(response.status)) {
432+
await push_fetched(undefined, false);
433+
return undefined;
434+
}
435+
430436
if (!body || typeof body === 'string') {
431437
await push_fetched(body, false);
432438
}
@@ -444,7 +450,8 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
444450

445451
if (key === 'json') {
446452
return async () => {
447-
return JSON.parse(await text());
453+
const body = await text();
454+
return body ? JSON.parse(body) : undefined;
448455
};
449456
}
450457

packages/kit/src/runtime/server/page/types.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export interface Fetched {
66
method: string;
77
request_body?: string | ArrayBufferView | null;
88
request_headers?: HeadersInit | undefined;
9-
response_body: string;
9+
response_body: string | undefined;
1010
response: Response;
1111
is_b64?: boolean;
1212
}

packages/kit/test/apps/basics/src/routes/load/+page.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<a href="/load/fetch-relative">fetch relative</a>
1010
<a href="/load/fetch-credentialed">fetch credentialed</a>
1111
<a href="/load/fetch-request-headers">fetch headers</a>
12+
<a href="/load/fetch-no-body">fetch no body</a>
1213
<a href="/load/large-response">large response</a>
1314
<a href="/load/raw-body">raw body</a>
1415
<a href="/load/server-fetch-request">server fetch request</a>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export async function load({ fetch }) {
2+
const response = await fetch('/load/fetch-no-body/endpoint');
3+
4+
return {
5+
ok: response.ok,
6+
body: await response.text()
7+
};
8+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let { data } = $props();
3+
</script>
4+
5+
<h1>ok: {data.ok}</h1>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function GET() {
2+
return new Response(undefined, {
3+
status: 204
4+
});
5+
}

packages/kit/test/apps/basics/test/test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ test.describe('Load', () => {
599599
expect(await page.textContent('.aborted-during-request')).toBe('Aborted during request: true');
600600
expect(await page.textContent('.successful-data')).toContain('"message":"success"');
601601
});
602+
603+
test('event.fetch handles response without body', async ({ page }) => {
604+
await page.goto('/load/fetch-no-body');
605+
expect(await page.textContent('h1')).toBe('ok: true');
606+
});
602607
});
603608

604609
test.describe('Nested layouts', () => {

0 commit comments

Comments
 (0)