Web Dev Cody
Web Dev Cody12mo ago

Issue with Cors

I'm trying to add an http endpoint to convex which any application is able to send a request to, but it seems like maybe using * doesn't work? this is my current handler for options, but it fails when my other domain tries to hit it
http.route({
path: '/api/v1/feedback',
method: 'OPTIONS',
handler: httpAction(async (_, request) => {
const headers = request.headers;
if (
headers.get('Origin') !== null &&
headers.get('Access-Control-Request-Method') !== null &&
headers.get('Access-Control-Request-Headers') !== null
) {
return new Response(null, {
headers: new Headers({
'Access-Control-Allow-Origin': process.env.ALLOW_ORIGIN!,
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type, Digest',
'Access-Control-Max-Age': '86400',
}),
});
} else {
return new Response();
}
}),
});
http.route({
path: '/api/v1/feedback',
method: 'OPTIONS',
handler: httpAction(async (_, request) => {
const headers = request.headers;
if (
headers.get('Origin') !== null &&
headers.get('Access-Control-Request-Method') !== null &&
headers.get('Access-Control-Request-Headers') !== null
) {
return new Response(null, {
headers: new Headers({
'Access-Control-Allow-Origin': process.env.ALLOW_ORIGIN!,
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type, Digest',
'Access-Control-Max-Age': '86400',
}),
});
} else {
return new Response();
}
}),
});
12 Replies
Web Dev Cody
Web Dev CodyOP12mo ago
ALLOW_ORIGIN is * I'm guessing I need to use the request object and get the origin on the request somehow maybe request.referrer is what I'm looking for.. let me try it interesting, request.referrer crashes my httpAction Not implemented: get referrer for Request yeah, stuck on this for now
erquhart
erquhart12mo ago
Before the referrer change, what was happening when a request came in? What was the initial error?
jamwt
jamwt12mo ago
@ian any idea on this one?
ian
ian12mo ago
A couple things come to mind: - Avoid setting cache headers off the bat until you get it working to avoid debugging against cached results - Add a "Vary: Origin" header if you're returning the origin in the response, so requests from different origins don't have a cached response of the other origin - The * should work when there aren't credentials being sent up - but needs a value when passing up with credentials. you can set credentials to "omit" if you don't need them - Start by hard-coding the origins - have you checked the ORIGIN header? It'll be set for preflight requests I believe
Web Dev Cody
Web Dev CodyOP12mo ago
the options request was failing with cors when it was set to * trying some of those now
Web Dev Cody
Web Dev CodyOP12mo ago
k... it's working now.
No description
Web Dev Cody
Web Dev CodyOP12mo ago
although I'm still trying to understand why I read Vary: 'Origin' prevents the browser from caching headers but does both the options and post endpoint need it?
ian
ian12mo ago
I believe just the options request, as it's the caching behavior for the pre-flight response It seems to not be used for the preflight, which already has the cache key based on the origin, but only the regular request, which differs based on origin b/c of the response headers to match the origin. so if you request from localhost:8000 and mysite.vercel.app and each one returns the origin of the requesting site, they won't see the cached origin of the other
Web Dev Cody
Web Dev CodyOP12mo ago
is it because I have Vary: 'origin' lower case?
ian
ian12mo ago
And what about 'Access-Control-Allow-Origin': headers.get('Origin'), when the origin matches some list of allowed ones?
ian
ian12mo ago
I'm not sure Vary: 'Origin' is playing a big part, just noticed it while going through https://httptoolkit.com/will-it-cors which I use when I forget these things
Will It CORS? - a CORS debugging tool that actually works.
Literally nobody understands CORS, except this one magic web page
ian
ian12mo ago
I've been meaning to make a cors helper that would do something like:
routeWithCORS(http, {
path: "/api/v1/feedback",
POST: handler
GET: handler
}, {
allowCredentials: true,
allowOrigins: ["localhost:8000", "myapp.vercel.app"], // * only accepted if allow credentials is false
allowCustomHeaders: [...],
cacheMaxAge: 86400,
allowTiming: true,
}
routeWithCORS(http, {
path: "/api/v1/feedback",
POST: handler
GET: handler
}, {
allowCredentials: true,
allowOrigins: ["localhost:8000", "myapp.vercel.app"], // * only accepted if allow credentials is false
allowCustomHeaders: [...],
cacheMaxAge: 86400,
allowTiming: true,
}
with defaults that don't allow credentials, accept any origin and headers, cache for 86400, and allow timing. It'd register each of the methods separately, then register OPTIONS for the same path that sends the right response. If credentials are passed up and no origins are allowed, it'll send a helpful error of how to either add origins or not send credentials from the client But I haven't been making an app that needs it, so I haven't invested in it. If you want to do a video on CORS and make the helper, by all means! Or lmk if you want me to take a stab at the helper if it'd be useful for ya

Did you find this page helpful?