Problem Encountered with CORS in Deno Server
Tags: deno, cors, webdev, oakcors
Published: 2024-02-04 23:28:10

## Problem Encountered with CORS in Deno Server

Recently, I encountered an issue while developing a server using Deno. My objective was to enable CORS (Cross-Origin Resource Sharing) requests utilizing the `oakCors` middleware. Despite setting it up as per the [documentation](https://deno.land/x/cors@v1.2.2), CORS handling did not function as expected.

### The Scenario

I employed Deno's Oak framework to create the server and handle incoming requests from the frontend. Below is a snippet of the code used (some parts are modified for brevity and clarity):

```typescript
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
import { oakCors } from "https://deno.land/x/cors/mod.ts";

const router = new Router();
router.post("/", async (context) => {
    const body = await context.request.body();
    console.log(body.text());
});

const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());

// Enabling CORS for port 5173 on localhost using oakCors
app.use(
  oakCors({
    origin: "http://localhost:5173",
    optionsSuccessStatus: 200,
    methods: "POST, OPTIONS",
  }),
);

await app.listen({ port: 8000 });
```

Despite configuring the server to accept CORS requests from `http://localhost:5173`, requests to the server were being rejected due to CORS errors.

### Analysis

It appears that the 'oakCors' middleware is not working correctly, and the CORS headers are not being added, as indicated by the error message I received:

```
Access to fetch at 'http://localhost:8000/api/generate' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

### Solution

After some trial and error, I discovered that moving the configuration of `oakCors` before defining the routes resolved the issue. 
```typescript
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
import { oakCors } from "https://deno.land/x/cors/mod.ts";

const app = new Application();

// Enabling CORS for port 5173 on localhost using oakCors
// make sure to initialize oakCors before the routers
app.use(
  oakCors({
    origin: "http://localhost:5173",
    optionsSuccessStatus: 200,
    methods: "POST, OPTIONS",
  }),
);

const router = new Router();
router.post("/", async (context) => {
    const body = await context.request.body();
    console.log(body.text());
});


app.use(router.routes());
app.use(router.allowedMethods());

await app.listen({ port: 8000 });
```


I learned that I should configure middleware before the routes' are defined.

### Remaining Challenge

According to the chapter "Enable CORS for a Single Route" of [the official docs](https://deno.land/x/cors@v1.2.2), these codes would work but didn't.

```server.ts
const corsOptions: oakCors.Options = {
  origin: "http://localhost:5173",
  optionsSuccessStatus: 200,
};

router.post("/", oakCors(corsOptions), (context) => {
    const body = await context.request.body;
    console.log(body.text());
});

```

Although this issue remains unresolved at present, it does not impede the functionality of the server as I have implemented a workaround that meets my current requirements.