Dealing with CORS
So you’ve encountered some CORS problems and are on the hunt for the solution? You’re in the right spot.
Here’s a good resource talking about CORS in general, in case you don’t fully understand what’s wrong.
Simple CORS -- Middleware
As per the above link, “simple” requests involve GET
, HEAD
, or POST
requests. You can CORS enable all the routes affected by some middleware
by
doing the following:
import { FreshContext } from "$fresh/server.ts";
export async function handler(req: Request, ctx: FreshContext) {
const origin = req.headers.get("Origin") || "*";
const resp = await ctx.next();
const headers = resp.headers;
headers.set("Access-Control-Allow-Origin", origin);
headers.set("Access-Control-Allow-Credentials", "true");
headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With",
);
headers.set(
"Access-Control-Allow-Methods",
"POST, OPTIONS, GET, PUT, DELETE",
);
return resp;
}
Complex CORS -- Middleware
What about for one of the other HTTP methods? Then you’ll need to be able to
deal with “preflight requests”. Let’s imagine you’re trying to support a
DELETE
route. Then you’d need to do something like this:
import { FreshContext } from "$fresh/server.ts";
export async function handler(req: Request, ctx: FreshContext) {
if (req.method == "OPTIONS") {
const resp = new Response(null, {
status: 204,
});
const origin = req.headers.get("Origin") || "*";
const headers = resp.headers;
headers.set("Access-Control-Allow-Origin", origin);
headers.set("Access-Control-Allow-Methods", "DELETE");
return resp;
}
const origin = req.headers.get("Origin") || "*";
const resp = await ctx.next();
const headers = resp.headers;
headers.set("Access-Control-Allow-Origin", origin);
headers.set("Access-Control-Allow-Credentials", "true");
headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With",
);
headers.set(
"Access-Control-Allow-Methods",
"POST, OPTIONS, GET, PUT, DELETE",
);
return resp;
}
These complex results require a two step process:
- the browser makes an `OPTIONS` request to find out about the allowed methods
- the browser makes the actual request
So you can see the middleware has some special handling to deal with OPTIONS
requests.
CORS in Routes
Of course there’s no reason why you need to use middleware in order to solve this. The headers can be set directly in the handler as well.