From 5dcf6ffec2d4f2e012cf4aed610bb45b578e7f1c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 6 Jan 2023 11:38:10 -0500 Subject: [PATCH 1/2] error in dev mode if global fetch is used with relative URL - closes #7976 --- .changeset/cuddly-cows-vanish.md | 5 +++++ .../docs/10-getting-started/40-web-standards.md | 2 +- packages/kit/src/exports/vite/dev/index.js | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changeset/cuddly-cows-vanish.md diff --git a/.changeset/cuddly-cows-vanish.md b/.changeset/cuddly-cows-vanish.md new file mode 100644 index 000000000000..e4b8aa5891cf --- /dev/null +++ b/.changeset/cuddly-cows-vanish.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +Error in dev mode if global `fetch` is used with relative URL diff --git a/documentation/docs/10-getting-started/40-web-standards.md b/documentation/docs/10-getting-started/40-web-standards.md index 58fd9fbaf252..a12f534cfae3 100644 --- a/documentation/docs/10-getting-started/40-web-standards.md +++ b/documentation/docs/10-getting-started/40-web-standards.md @@ -12,7 +12,7 @@ In particular, you'll get comfortable with the following: SvelteKit uses [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) for getting data from the network. It's available in [hooks](/docs/hooks) and [server routes](/docs/routing#server) as well as in the browser. -> A special version of `fetch` is available in [`load`](/docs/load) functions for invoking endpoints directly during server-side rendering, without making an HTTP call, while preserving credentials. (To make credentialled fetches in server-side code outside `load`, you must explicitly pass `cookie` and/or `authorization` headers.) It also allows you to make relative requests, whereas server-side `fetch` normally requires a fully qualified URL. +> A special version of `fetch` is available in [`load`](/docs/load) functions, [server hooks](/docs/hooks#server-hooks) and [API routes](/docs/routing#server) for invoking endpoints directly during server-side rendering, without making an HTTP call, while preserving credentials. (To make credentialled fetches in server-side code outside `load`, you must explicitly pass `cookie` and/or `authorization` headers.) It also allows you to make relative requests, whereas server-side `fetch` normally requires a fully qualified URL. Besides `fetch` itself, the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) includes the following interfaces: diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 571db3d223b9..08df5b8650e2 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -29,6 +29,19 @@ export async function dev(vite, vite_config, svelte_config) { installPolyfills(); } + const fetch = globalThis.fetch; + globalThis.fetch = (info, init) => { + if (typeof info === 'string') { + if (new URL(info, 'fake://fake').protocol === 'fake:') { + throw new Error( + `Cannot use relative URL (${info}) with global fetch — use \`event.fetch\` instead: https://kit.svelte.dev/docs/web-standards#fetch-apis` + ); + } + } + + return fetch(info, init); + }; + sync.init(svelte_config, vite_config.mode); /** @type {import('types').Respond} */ From 857e108549cb09445e360da7700f9ce895c9ea69 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 9 Jan 2023 10:37:36 +0100 Subject: [PATCH 2/2] Update packages/kit/src/exports/vite/dev/index.js Co-authored-by: Rich Harris --- packages/kit/src/exports/vite/dev/index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 08df5b8650e2..f1021713cdb1 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -31,12 +31,10 @@ export async function dev(vite, vite_config, svelte_config) { const fetch = globalThis.fetch; globalThis.fetch = (info, init) => { - if (typeof info === 'string') { - if (new URL(info, 'fake://fake').protocol === 'fake:') { - throw new Error( - `Cannot use relative URL (${info}) with global fetch — use \`event.fetch\` instead: https://kit.svelte.dev/docs/web-standards#fetch-apis` - ); - } + if (typeof info === 'string' && !/^\w+:\/\//.test(info)) { + throw new Error( + `Cannot use relative URL (${info}) with global fetch — use \`event.fetch\` instead: https://kit.svelte.dev/docs/web-standards#fetch-apis` + ); } return fetch(info, init);