Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bun.serve not supporting CORS #5466

Closed
satyavh opened this issue Sep 15, 2023 · 6 comments
Closed

Bun.serve not supporting CORS #5466

satyavh opened this issue Sep 15, 2023 · 6 comments
Labels
enhancement New feature or request

Comments

@satyavh
Copy link

satyavh commented Sep 15, 2023

What is the problem this feature would solve?

Handle CORS, which is one of the basics of a HTTP server. Without CORS settings Bun.serve is kind of useless.

What is the feature you are proposing to solve the problem?

Support CORS settings

What alternatives have you considered?

Fall back to Express

@satyavh satyavh added the enhancement New feature or request label Sep 15, 2023
@sudityashrivastav
Copy link

Go with your alternative

@controversial
Copy link
Contributor

controversial commented Sep 15, 2023

Bun.serve absolutely supports CORS—just add CORS headers to your response:

Bun.serve({
  fetch(req) {
    const res = new Response('hello world');
    res.headers.set('Access-Control-Allow-Origin', '*');
    res.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    // add Access-Control-Allow-Headers if needed
    return res;
  },
});

Bun.serve is an intentionally minimal API, closely following web standards (fetch, Request, and Response). You don’t need a package or a built-in setting just to add 1–3 headers to your server responses!

@Electroid
Copy link
Contributor

As @controversial mentioned, CORS is possible using Bun.serve.

@lliamscholtz
Copy link

lliamscholtz commented Sep 30, 2023

If you've added these headers to Bun.serve:

res.headers.set('Access-Control-Allow-Origin', '*');
res.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

and are still getting CORS issues via a browser your Preflight OPTIONS request might still be getting blocked.

To solve this, I created a catch-all preflight requests method handler in my server.ts file:

const CORS_HEADERS = {
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'OPTIONS, POST',
        'Access-Control-Allow-Headers': 'Content-Type',
    },
};

Bun.serve({
    async fetch(req) {

        // Handle CORS preflight requests
        if (req.method === 'OPTIONS') {
            const res = new Response('Departed', CORS_HEADERS);
            return res;
        }
        
        const url = new URL(req.url);
        if (url.pathname === '/' && req.method === 'POST') {
            const { foo } = await req.json();      
            . . .
            return new Response(
                JSON.stringify({ foo: bar }),
                CORS_HEADERS
            );

@sWalbrun
Copy link

sWalbrun commented Nov 6, 2023

You approach @lliamscholtz did work out for me with a slight change as the client had a
Access-Control-Request-Headers: Content-Type, Authorization as further request header. In this case I had to slightly adjust the code:

const CORS_HEADERS = {
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'OPTIONS, POST',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
};

Bun.serve({
    async fetch(req) {

        // Handle CORS preflight requests
        if (req.method === 'OPTIONS') {
            const res = new Response('Departed', CORS_HEADERS);
            return res;
        }
        
        const url = new URL(req.url);
        if (url.pathname === '/' && req.method === 'POST') {
            const { foo } = await req.json();      
            . . .
            return new Response(
                JSON.stringify({ foo: bar }),
                CORS_HEADERS
            );

@lmachens
Copy link

Or extend the Response:

import { BodyInit, ResponseInit } from "undici-types";

export class ClientResponse extends Response {
  constructor(body?: BodyInit, init?: ResponseInit) {
    super(body, init);
    this.headers.set("Access-Control-Allow-Origin", "*");
    this.headers.set("Access-Control-Allow-Methods", "OPTIONS, GET");
    this.headers.set("Access-Control-Allow-Headers", "Content-Type");
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants