Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/honest-cobras-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': major
Comment thread
teemingc marked this conversation as resolved.
Outdated
---

fix: `fetch` not working when URL is same host but different than `paths.base`
8 changes: 6 additions & 2 deletions packages/kit/src/runtime/server/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
request.headers.delete('origin');
}

if (url.origin !== event.url.origin) {
const decoded = decodeURIComponent(url.pathname);

if (
url.origin !== event.url.origin ||
(paths.base && decoded !== paths.base && !decoded.startsWith(`${paths.base}/`))
) {
Comment thread
PatrickG marked this conversation as resolved.
// Allow cookie passthrough for "credentials: same-origin" and "credentials: include"
// if SvelteKit is serving my.domain.com:
// - domain.com WILL NOT receive cookies
Expand All @@ -77,7 +82,6 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
// handle fetch requests for static assets. e.g. prebaked data, etc.
// we need to support everything the browser's fetch supports
const prefix = paths.assets || paths.base;
const decoded = decodeURIComponent(url.pathname);
const filename = (
decoded.startsWith(prefix) ? decoded.slice(prefix.length) : decoded
).slice(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
fetch('/request-abort', { headers: { accept: 'application/json' } }).then(
async (r) => (result = await r.json())
);
}, 100);
}, 50);
Comment thread
teemingc marked this conversation as resolved.
}

onMount(test_abort);
Expand Down
3 changes: 3 additions & 0 deletions packages/kit/test/apps/options/source/pages/+server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function GET() {
return new Response('root');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export async function load({ fetch }) {
const response = await fetch('/not-base-path/');
return {
fetchUrl: response.url,
fetchResponse: await response.text()
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
/** @type {import('./$types').PageProps} */
const { data } = $props();
</script>

<p data-testid="fetch-url">{data.fetchUrl}</p>
<p data-testid="fetch-response">{data.fetchResponse}</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export async function load({ fetch }) {
// fetch to root with trailing slash
const response1 = await fetch('/');
// fetch to root without trailing slash
const response2 = await fetch('');
// fetch to root with custom base path with trailing slash
const response3 = await fetch('/path-base/');
// fetch to root with custom base path without trailing slash
const response4 = await fetch('/path-base');

return {
fetchUrl1: response1.url,
fetchUrl2: response2.url,
fetchUrl3: response3.url,
fetchUrl4: response4.url,
fetchResponse1: await response1.text(),
fetchResponse2: await response2.text(),
fetchResponse3: await response3.text(),
fetchRedirect4: response4.headers.get('location')
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script>
/** @type {import('./$types').PageProps} */
const { data } = $props();
</script>

<h2>Fetch URLs</h2>

<dl>
<dt>fetch1-url</dt>
<dd data-testid="fetch1-url">{data.fetchUrl1}</dd>
<dt>fetch2-url</dt>
<dd data-testid="fetch2-url">{data.fetchUrl2}</dd>
<dt>fetch3-url</dt>
<dd data-testid="fetch3-url">{data.fetchUrl3}</dd>
<dt>fetch4-url</dt>
<dd data-testid="fetch4-url">{data.fetchUrl4}</dd>
</dl>

<h2>Fetch Responses</h2>
<dl>
<dt>fetch1-response</dt>
<dd data-testid="fetch1-response">{data.fetchResponse1}</dd>
<dt>fetch2-response</dt>
<dd data-testid="fetch2-response">{data.fetchResponse2}</dd>
<dt>fetch3-response</dt>
<dd data-testid="fetch3-response">{data.fetchResponse3}</dd>
<dt>fetch4-redirect</dt>
<dd data-testid="fetch4-redirect">{data.fetchRedirect4}</dd>
</dl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function GET() {
return new Response('relative');
}
35 changes: 35 additions & 0 deletions packages/kit/test/apps/options/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,39 @@ test.describe('Async', () => {
await expect(page.locator('h1', { hasText: 'Page B' })).toBeVisible();
expect(logs).toEqual(['mounted', 'navigated']);
});

test.describe('Fetch', () => {
test('fetch outside base path succeeds', async ({ page, baseURL }) => {
await page.goto('/path-base/fetch/link-outside-base/');
expect(await page.locator('[data-testid="fetch-url"]').textContent()).toContain(
`${baseURL}/not-base-path/`
);
expect(await page.locator('[data-testid="fetch-response"]').textContent()).toContain(
'did you mean to visit'
);
});

test('fetch to root succeeds', async ({ page, baseURL }) => {
await page.goto('/path-base/fetch/link-root/');
// fetch to root with trailing slash
expect(await page.locator('[data-testid="fetch1-url"]').textContent()).toContain(
`${baseURL}/`
);
expect(await page.locator('[data-testid="fetch1-response"]').textContent()).toContain('root');

// fetch to root without trailing slash should be relative
expect(await page.locator('[data-testid="fetch2-url"]').textContent()).toBeFalsy();
expect(await page.locator('[data-testid="fetch2-response"]').textContent()).toBe('relative');

// fetch to root with custom base path with trailing slash
expect(await page.locator('[data-testid="fetch3-url"]').textContent()).toBeFalsy();
expect(await page.locator('[data-testid="fetch3-response"]').textContent()).toBe('root');

// fetch to root with custom base path without trailing slash
expect(await page.locator('[data-testid="fetch4-url"]').textContent()).toBeFalsy();
expect(await page.locator('[data-testid="fetch4-redirect"]').textContent()).toBe(
'/path-base/'
);
});
});
});
Loading