diff --git a/packages/kit/src/runtime/server/constants.js b/packages/kit/src/runtime/server/constants.js new file mode 100644 index 000000000000..e52707a19ca7 --- /dev/null +++ b/packages/kit/src/runtime/server/constants.js @@ -0,0 +1 @@ +export const NULL_BODY_STATUS = [101, 103, 204, 205, 304]; diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index dbe4e7c2ef17..8d06de88038e 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -6,6 +6,7 @@ import { with_request_store, merge_tracing } from '@sveltejs/kit/internal/server import { record_span } from '../../telemetry/record_span.js'; import { clarify_devalue_error, get_node_type } from '../utils.js'; import { base64_encode, text_decoder } from '../../utils.js'; +import { NULL_BODY_STATUS } from '../constants.js'; /** * Calls the user's server `load` function. @@ -345,7 +346,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts) const proxy = new Proxy(response, { get(response, key, _receiver) { /** - * @param {string} body + * @param {string | undefined} body * @param {boolean} is_b64 */ async function push_fetched(body, is_b64) { @@ -427,6 +428,11 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts) async function text() { const body = await response.text(); + if (body === '' && NULL_BODY_STATUS.includes(response.status)) { + await push_fetched(undefined, false); + return undefined; + } + if (!body || typeof body === 'string') { await push_fetched(body, false); } @@ -444,7 +450,8 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts) if (key === 'json') { return async () => { - return JSON.parse(await text()); + const body = await text(); + return body ? JSON.parse(body) : undefined; }; } diff --git a/packages/kit/src/runtime/server/page/types.d.ts b/packages/kit/src/runtime/server/page/types.d.ts index 7e501b1ab418..300e05fefbe9 100644 --- a/packages/kit/src/runtime/server/page/types.d.ts +++ b/packages/kit/src/runtime/server/page/types.d.ts @@ -6,7 +6,7 @@ export interface Fetched { method: string; request_body?: string | ArrayBufferView | null; request_headers?: HeadersInit | undefined; - response_body: string; + response_body: string | undefined; response: Response; is_b64?: boolean; } diff --git a/packages/kit/test/apps/basics/src/routes/load/+page.svelte b/packages/kit/test/apps/basics/src/routes/load/+page.svelte index 9c46790b79c9..fa1ea632d30e 100644 --- a/packages/kit/test/apps/basics/src/routes/load/+page.svelte +++ b/packages/kit/test/apps/basics/src/routes/load/+page.svelte @@ -9,6 +9,7 @@ fetch relative fetch credentialed fetch headers +fetch no body large response raw body server fetch request diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/+page.js b/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/+page.js new file mode 100644 index 000000000000..c9a47c2044a0 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/+page.js @@ -0,0 +1,8 @@ +export async function load({ fetch }) { + const response = await fetch('/load/fetch-no-body/endpoint'); + + return { + ok: response.ok, + body: await response.text() + }; +} diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/+page.svelte b/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/+page.svelte new file mode 100644 index 000000000000..2413817339b1 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/+page.svelte @@ -0,0 +1,5 @@ + + +

ok: {data.ok}

diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/endpoint/+server.js b/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/endpoint/+server.js new file mode 100644 index 000000000000..82acf885595d --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/load/fetch-no-body/endpoint/+server.js @@ -0,0 +1,5 @@ +export function GET() { + return new Response(undefined, { + status: 204 + }); +} diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 55db0bf20db6..a2df7195dd21 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -599,6 +599,11 @@ test.describe('Load', () => { expect(await page.textContent('.aborted-during-request')).toBe('Aborted during request: true'); expect(await page.textContent('.successful-data')).toContain('"message":"success"'); }); + + test('event.fetch handles response without body', async ({ page }) => { + await page.goto('/load/fetch-no-body'); + expect(await page.textContent('h1')).toBe('ok: true'); + }); }); test.describe('Nested layouts', () => {