-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[fix] fetch erroring on Cloudflare #7192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: adaffd4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
We very much would like to avoid having any code specific to a particular hosting platform inside SvelteKit core. I don't have a suggestion off the top of my head for what existing adapter API would work for providing the equivalent functionality. I do think it would be better to make the API a bit more flexible though so the Cloudflare adapter can do it itself, rather than having Cloudflare-specific code life in the core framework and thus in all apps for any platform. |
|
I definitely agree that keeping platform specific code outside of the core is good, and that the Cloudflare adapter taking care of it would be the best solution. However, this issue cripples deploying to Cloudflare, making it for all intents and purposes impossible on modern versions of SvelteKit. Would it be possible to have this patch until a better solution can be made? |
|
It can be worked around on cloudflare workers when deployed via wrangler, see #6739 (comment) and #6739 (comment). Not sure how that could be applied to cloudflare pages. The proposed fix here not only adds platform specific code to core but also makes assumptions about the values provided, which won't work for everyone. A more generic solution could take a clue from the handleFetch workaround, offering a way for adapters to provide runtime bits to kit. But it feels weird that cloudflare throws this error. Did you raise it with them too? |
|
I've tried both of those workarounds but neither work when deployed to Pages (with wrangler). I am currently using my patched version as a workaround, thank you for the suggestion. I haven't raised this with Cloudflare, but I will do that now. |
|
This is sadly a "documented" limit in Cloudflare: https://community.cloudflare.com/t/how-to-get-request-mode-from-cloudflare-worker/421996 (I really hate they way they implemented it rather than just ignoring the property entirely), so I doubt they are going to solve anything on their side right now :( |
* [fix] fetch erroring on Cloudflare Fixes #6739 * alternative to #7192 Co-authored-by: The Noah <[email protected]>
|
Closed in favour of #7453 (which includes this branch) — hopefully it's sufficient 🤞 |
|
(and thank you!) |
|
@Rich-Harris @dummdidumm i just tested this with newest ( Reproduction repo:Preview in Cloudflare Pages:https://sveltekit-server-endpoint-test.pages.dev/pikachu Screenshots
|
|
@allozaur It's working for me using both wrangler publish and pages (src). |
|
@Deebster your example doesn't use
import { error, json } from "@sveltejs/kit";
export async function GET(/** @type{ { params: any } } */ { params }) {
try {
const result = await fetch(`https://pokeapi.co/api/v2/pokemon/${params.name}`)
const data = await result.json();
return json(data);
} catch (e) {
throw error(404);
}
}
import { error } from "@sveltejs/kit";
export async function load(/** @type{ { fetch: any, params: any } } */ { fetch, params }) {
const req = await fetch(`/api/pokemon/${params.name}`, { mode: "cors" });
const res = await req.json();
if (res) {
return {
pokemon: res,
}
}
throw error(404);
}
<script>
/**
* @type {any}
*/
export let data;
$: console.log(1, data);
</script>
<h1>{data.pokemon.name}</h1>
<img src={data.pokemon.sprites.front_default} alt={data.pokemon.name} />What's really strange is that when you access the data from the |
|
Hmm, I am assuming the fix works because I've set I'm wondering if you could be hitting a separate problem: there's a limitation with Cloudflare whereby worker-to-worker requests require setting up a service binding*. This assumes that SvelteKit does a full request instead of internally routing the call - I thought it wouldn't do a real request but I can't see that in the docs. Also, this doesn't explain why your previous fix worked, but I'll hit send anyway in case this is helpful. * In my actual project, I have a separate API worker on a subdomain and needed to use a |
|
@Deebster @Rich-Harris @dummdidumm i managed to get this working |
|
what was the problem / what was the fix? |
|
I supposed it's been fixed here 9f57ff3 |
Is there any chance you could share the working code with me? I seem to be comprehensively stuck on this same issue. Looking at a working example would be very helpful. |
|
@Adrian-MID Not sure if this helps but we were having issues when copying a request to replace the URL to make internal requests during SSR. Initially we had this, which did not work for Cloudflare Pages because Request.mode is undefined and SvelteKit attempts to call it internally when making the fetch request: export const handleFetch = (({ event, request, fetch }) => {
if (request.url.startsWith(PUBLIC_URL)) {
if (INTERNAL_URL) {
request = new Request(
request.url.replace(PUBLIC_URL, INTERNAL_URL),
request
);
}
}
return fetch(request);
}) satisfies HandleFetch;So we ended up changing it to this and it works fine because it avoids the Request.mode call: export const handleFetch = (({ event, request, fetch }) => {
if (request.url.startsWith(PUBLIC_URL)) {
if (INTERNAL_URL) {
return fetch(request.url.replace(PUBLIC_URL, INTERNAL_URL), {
method: request.method,
body: request.body,
mode: 'cors',
credentials: 'include',
headers: request.headers,
});
}
}
return fetch(request);
}) satisfies HandleFetch;It's a hack but it works, and the reason it does is because SvelteKit does the following when attempting to get the request mode: fetch: async (info2, init3) => {
...
mode = (info2 instanceof Request ? info2.mode : init3?.mode) ?? "cors"; |


Fixes #6739
Ever since #6565 calling
fetchin a load function fails on Cloudflare (Pages+Workers). This solution checks for the uniquecfobject that Cloudflare sets to bypass properties Cloudflare does not provide, assuming reasonable defaults.Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm testand lint the project withpnpm lintandpnpm checkChangesets
pnpm changesetand following the prompts. All changesets should bepatchuntil SvelteKit 1.0