Open tctree333 opened 1 year ago
I do experience this issue on your Stackblitz reproduction, but when I download the project and run it locally, I do not.
SvelteKit intercepts fetch
requests that could come from either the server or the client, and "simulates" CORS on the ones that run on the server. It's a good idea, because otherwise people could be thinking they're all good when their site works in SSR mode, but then when a user navigates and the same request is done as a CORS fetch
via the browser, it could fail.
But in your situation, that check is falsely asserting that the simulated CORS check has failed. But... only on StackBlitz. There are some differences to how Undici and StackBlitz web containers handle fetches...
Here's SvelteKit making an SSR fetch
via Undici:
{
"user-agent": "undici",
"accept": "*/*",
"accept-encoding": "br, gzip, deflate",
"accept-language": "*",
"origin": "http://127.0.0.1:5173",
"sec-fetch-mode": "cors",
"x-forwarded-for": "47.196.22.77",
"x-forwarded-host": "sveltekit.free.beeceptor.com",
"x-forwarded-proto": "https"
}
And here's Firefox making one through StackBlitz:
{
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0",
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "*",
"cache-control": "no-cache",
"origin": "https://corserrorduringserverrenderrepro-f5o4.w-corp.staticblitz.com",
"pragma": "no-cache",
"referer": "https://corserrorduringserverrenderrepro-f5o4.w-corp.staticblitz.com/",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "cross-site",
"te": "trailers",
"x-forwarded-for": "47.196.22.77",
"x-forwarded-host": "sveltekit.free.beeceptor.com",
"x-forwarded-proto": "https"
}
But the weird thing is that both requests are getting the a "access-control-allow-origin": "*"
response header... but the StackBlitz version thinks it is getting no access-control-allow-origin
header.
I have the same exact issue on a GitPod repo. I needed to disable csrf
in svelte.config.js
in order to continue working on it, and will need to remember resetting it in production. I guess I could something like csrf: env.prod === 'dev'
, but it feels weird to disable it completely during development.
Perhaps an ORIGIN=...
variable in the .env
file could solve this?
It might be an issue with the test endpoint in the example since httpbin returns an access-control-allow-origin
that matches the origin (or is *
). When an endpoint returns a proper access-control-allow-origin
that's set to a domain, SvelteKit throws an error during server rendering (in dev and build). When I was trying it on StackBlitz it gave an error with httpbin but that might be a different issue considering that the header should be set.
If someone knows of a test endpoint that sets an access-control-allow-origin
that might be a better test endpoint.
It seems that the browser removes the access-control-allow-origin
prior to handing it to the user's JavaScript - when doing response.headers.get('access-control-allow-origin')
, it doesn't show up. I assume that Stackblitz and GitPod either have no control to forward these headers (because they can't access them either) or are removing them before passing it on.
We can't fix this without removing the sensible checks to ensure things run on the client and server the same, so I think the best we can do is document this. A workaround (which SvelteKit will warn you about, but you can ignore it in this case) is to use the global fetch
in these cases.
I have the same exact issue on a GitPod repo. I needed to disable
csrf
insvelte.config.js
in order to continue working on it, and will need to remember resetting it in production. I guess I could something likecsrf: env.prod === 'dev'
, but it feels weird to disable it completely during development.Perhaps an
ORIGIN=...
variable in the.env
file could solve this?
I am also developing on Gitpod and am running into this issue. I use the same workaround as @Haffi921.
I am facing same issue. During production there would be different hosts, event.url.origin
matches to a k8s container and not the user facing hostname. This creates CORS on server side because event.url.origin
is never going to match user facing hostname, which BE api would be accepting in the origin
header.
We cannot use no-cors
on server as universal fetch returns an empty body response which is not useful at all.
We need a way to set the initial event.url.origin
which is going to be used on all the cors requests going forward. Or better would be to not use 'cors' during server side rendering.
@itssumitrai does the documentation below help resolve your issue? Does setting ORIGIN
to your user facing hostname help?
https://kit.svelte.dev/docs/adapter-node#environment-variables-origin-protocolheader-and-hostheader
Any updates?
@eltigerchino
@itssumitrai does the documentation below help resolve your issue? Does setting
ORIGIN
to your user facing hostname help? https://kit.svelte.dev/docs/adapter-node#environment-variables-origin-protocolheader-and-hostheader
Sadly it doesn't work.
What I don't understand is why fetch
in +page.server.ts
works, but not +page.ts
during SSR 🙄
What I don't understand is why
fetch
in+page.server.ts
works, but not+page.ts
during SSR 🙄
See #8314 (comment) for a full explanation. The recommended workaround for now is to use the global fetch
function instead of the one provided by the load
function.
The recommended workaround for now is to use the global fetch function instead of the one provided by the load function.
Global fetch
doesn't have access to cookies unfortunately, making authenticated requests impossible without passing cookies from +page.server.ts
first.
Describe the bug
When fetching an endpoint using CORS from a
+page.js
file, SvelteKit throws a CORS error when trying to render the page on the server, such as during development mode or prerendering for production. CORS doesn't seem to make sense in this context, since the fetch request is being performed on the server, which has no origin.This seems related to https://github.com/sveltejs/kit/issues/7441, but that issue involved
+page.server.js
files. In this issue, we want to perform the fetch on the client AND the server (during SSR/prerendering).Reproduction
https://stackblitz.com/edit/cors-error-during-server-render-repro?file=src%2Froutes%2Ftest%2F%2Bpage.js
Using the client-side navigation from
/
to/test
fetches data on the client perfectly fine, but doing a browser navigation/reload on the/test
page throws a CORS error on the server. Errors are also thrown when trying to run a build.Logs
No response
System Info
Severity
serious, but I can work around it
Additional Information
No response