javascriptcorsfetch-apibunelysiajs

How to fetch from a different origin and include cookies in the request


The problem is that i went to fetch cookies from my backend thats on a different origin than my front end. And i cant get cors to work with me. I am using bun with elysia.

This is an example i made to narrow down the problem.

The front end will create two cookies that i want to pas the backend. Then they get noted and create a new cookie and send it to the front end. This works if the orgin is the same. So if you go to localhost 1234 and create username and password cookies yourself in the developer tools it works
as intended.

I have tried including the header'Content-Type': 'application/json' and credentials: "include" in the fetch.

Backend

import Elysia from "elysia";
import cors from "@elysiajs/cors";

const app = new Elysia();

app.use(cors());

app.post("/cookies", ({ cookie: { username, password, icecream } }) => {
    icecream.value = "chocolate";
    console.log(username + ":" + password);
});

app.listen(1234);
console.log("Server up and running at http://localhost:1234");

Frontend

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="post">
        <input type="text" placeholder="username" name="username">
        <input type="text" placeholder="password" name="password">
        <button>submit</button>
    </form>
    <script>
        document.querySelector("form").addEventListener("submit", (e) => {
            e.preventDefault();
            console.log("submitting");
            document.cookie = `username=${document.querySelector("input[name='username']").value}`;
            document.cookie = `password=${document.querySelector("input[name='password']").value}`;

            fetch("http://localhost:1234/cookies", {
                method: "POST",
                headers: {
                    'Content-Type': 'application/json'
                },
                credentials: "include"
            })
            .then((response) => {
                console.log(response);
            });
        })

        
    </script>
</body>
</html>

Solution

  • https://github.com/elysiajs/elysia-cors/issues/48

    Thanks to gcraig-kaiza on github

    You need to add this

      .onAfterHandle(({ request, set }) => {
        // Only process CORS requests
        if (request.method !== "OPTIONS") return;
    
        const allowHeader = set.headers["Access-Control-Allow-Headers"];
        if (allowHeader === "*") {
          set.headers["Access-Control-Allow-Headers"] =
            request.headers.get("Access-Control-Request-Headers") ?? "";
        }
      })