Wrangler: [dev] provide option to control CORS

Created on 8 May 2020  Â·  15Comments  Â·  Source: cloudflare/wrangler

💡 Feature request

Overview and problem statement

Currently, there is no CORS setup on the wrangler dev server, which makes it impossible to call it from an app running on say localhost:3000 (create-react-app fro me) or proxy to it from another server (if I chose to let the react dev server proxy to the wrangler dev server).

It would be nice to provide an option to enable CORS, or maybe have it enabled by default since it's a local dev server anyway (?)

Basic example

wrangler dev --cors (?)

@EverlastingBugstopper, you the man! ;)

category - feature status - PR welcome subject - wrangler dev user report

Most helpful comment

@PierBover right on! Thanks for a super clear answer which worked beautifully. Appreciate it :).

All 15 comments

In case it helps, if I send a request from localhost:3000 I get the following error in my browser console:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8787/api/verify-phone. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

while if I proxy from the react dev server, I get this error from the react dev server:

[HPM] Error occurred while trying to proxy request /api/healthz from localhost:3000 to http://localhost:8787 (ECONNREFUSED) (studio/https:/nodejs.org/api/errors.html#errors_common_system_errors)

In the meantime this is how I solved it.

First respond to OPTIONS requests:

if (request.method === 'OPTIONS') {
  return new Response(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Credentials': 'true',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Origin': 'http://localhost:3000',
      'Access-Control-Allow-Headers': 'Content-Type'
    }
  });
}

If you plan on using custom headers you should add those to 'Access-Control-Allow-Headers'.

And then on all responses (200, 500, 400, etc) you have to add these headers:

response.headers.set('Access-Control-Allow-Origin', 'http://localhost:3000');
response.headers.set('Access-Control-Allow-Credentials', 'true');

Obviously change http://localhost:3000 to whatever port your front end is running from.

The Access-Control-Allow-Credentials header is for using cookies so I don't think it is necessary if you are using a JWT via an authorization header.

@PierBover right on! Thanks for a super clear answer which worked beautifully. Appreciate it :).

hey @tibotiber - i've been thinking about this a bit and was wondering if you run into the same CORS issues when interacting with a published Worker?

I think if we were to add this, it would be behind a flag instead of by default since it sets headers on responses that will not exist in production. I'm worried that providing the option for it would make it a bit confusing when something doesn't work in prod when it does work with wrangler dev. What do you think?

I'll be honest I only spent a little time as a web developer so my knowledge of CORS has a few holes :)

Yeah I think a flag for dev would be the best option for having a quick and easy way to enable CORS during local development.

IMO if someone needs CORS for production it would be best to add the headers manually like I showed for having more control.

@EverlastingBugstopper, no I don't run into this into production because I don't make requests from another origin in prod.

TLDR: I completely agree with @PierBover, with the extra addition that adding "CORS setup" as a snippet in the template gallery would be a worthy addition. If you point out where to add that, we can probably do it ;).

Now, the why, but it's longer:
Quick summary (probably useless but can save a search): CORS stands for Cross-origin resource sharing. By default a web server on chip.com will not respond to a request coming from dale.com, this is to protect resources from unintended access. You can however enable chip.com to respond from dale.com by setting CORS on the server. That would typically be done with some middleware, but the essential implementation is the one shared by @PierBover. So that's how they would share their nuts, sorry for the unrequested humor ;).

With this context, that's why I need CORS in dev but not in prod, because in dev, requests to my workers on localhost:8787 come from my react dev server on localhost:3000, another domain. In prod, however, the same requests come from the same domain. I think this is a fairly common use-case.

adding "CORS setup" as a snippet in the template gallery would be a worthy addition.

https://developers.cloudflare.com/workers/templates/pages/cors_header_proxy/

That makes sense @tibotiber! Thanks for the explanation :)

Thanks for sharing @ashleymichal, this looks way more complex than the few lines shared by @PierBover though 🤔.

It's probably production ready :)

My example was just a quick and dirty solution for local dev.

Oh right ;)

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@EverlastingBugstopper, no I don't run into this into production because I don't make requests from another origin in prod.

TLDR: I completely agree with @PierBover, with the extra addition that adding "CORS setup" as a snippet in the template gallery would be a worthy addition. If you point out where to add that, we can probably do it ;).

Now, the why, but it's longer:
Quick summary (probably useless but can save a search): CORS stands for Cross-origin resource sharing. By default a web server on chip.com will not respond to a request coming from dale.com, this is to protect resources from unintended access. You can however enable chip.com to respond from dale.com by setting CORS on the server. That would typically be done with some middleware, but the essential implementation is the one shared by @PierBover. So that's how they would share their nuts, sorry for the unrequested humor ;).

With this context, that's why I need CORS in dev but not in prod, because in dev, requests to my workers on localhost:8787 come from my react dev server on localhost:3000, another domain. In prod, however, the same requests come from the same domain. I think this is a fairly common use-case.

Hello! I use this in the same way when developing locally and it was never answered why the connection is refused when proxying from local react dev server? I do not agree that adding code for handling CORS is a good way to handle this. That code is only valid for development purposes since it will be served from the same hostname in production. For me it's bad design to add any special code for dev and debug that can eventually creep into production.

Proxy error: Could not proxy request /api/test from localhost:3000 to http://localhost:8787.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).

Any comments @signalnerve @ashleymichal ?

Thanks

Hey @dgitq and others having this issue- we definitely want local development to be smooth and make sure Wrangler dev works with common tools like create-react-app.

I attempted to reproduce this here https://github.com/nataliescottdavidson/reacttalktowranglerdev and was able to connect without seeing CORS issues. Let me know if I missed something.

If anybody reads this might help to prevent a few strokes: you need to restart the wrangler dev for some reason, otherwise no matter if you publish your workers or not, it will just be broken and keep throwing cors errors. The wrangler dev just relays the calls to my understanding, so not sure what is going on, but restarting it solved it for me and cors changes been picked up properly after.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

simplenotezy picture simplenotezy  Â·  5Comments

jahredhope picture jahredhope  Â·  4Comments

TownLake picture TownLake  Â·  3Comments

nickbalestra picture nickbalestra  Â·  5Comments

matthew-petrie picture matthew-petrie  Â·  4Comments