create react app: setupProxy keeps returning 401 blocked by CORS policy, not working for remote urls?

961 views Asked by At

this is my setupProxy code:

const { createProxyMiddleware } = require("http-proxy-middleware");

function proxy(app) {
  app.use(
    "/3.0/lists",
    createProxyMiddleware({
      target: "https://us19.api.mailchimp.com",
      changeOrigin: true,
    })
  );
 ...
}

my post request is depending on user input. e.g.:

https://us19.api.mailchimp.com/3.0/lists/123/members/432/tags 

but i keep getting this error: Access to XMLHttpRequest at

'https://us19.api.mailchimp.com/3.0/lists/7667u7/members/23er23ewe233/tags' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

but i already have it in setupProxy?

2

There are 2 answers

7
Quentin On BEST ANSWER

Your client doesn't know about the proxy middleware you have set up on your server. It can't automatically replace the original URL with the URL to the proxy. You have to do that yourself.

Change the client-side JS so it makes the request to /3.0/lists.

0
user3252327 On

When a frontend application makes a request to a resource from a different origin (localhost vs us19.api.mailchim.com), the browser makes a pre flight request to check if the server allows its entry point to be called from a different origin. If it's the case, it should reply to the preflight request with a Access-Control-Allow-Origin header.

The API could be very permissive and allow any origin:

Access-Control-Allow-Origin: *

Or the server could whitelist some origins and send specific header according to the origin. For instance:

Access-Control-Allow-Origin: localhost:3000

If no such header is in the response, the browser doesn't block the request with the error you mentioned.

In your case it would seem that us19.api.mailchimp.com/3.0/lists doesn't allow CORS calls. As such you have 2 solutions.

  1. If you have the control over the server, you could implement some CORS support by putting the header in the response
  2. Or your frontend could call your backend (no CORS since the origin is the same localhost:3000), then the backend would behave as a proxy and make the call to us19.api.mailchimp.com

According to your snippet, you are actually already going for the second option where your backend is a proxy to us19.api.mailchimp.com. However for this to work, the frontend should target /3.0/lists (so there would be no CORS checks since your frontend and server are both on localhost:3000) then your backend would forward the request to us19.api.mailchimp.com.

NOTE: As I have never used http-proxy-middleware, I assumed that there is no issue in your setup related to express and http-proxy-middleware. But this might also be an additional point to check.

EDIT

It would seem that the frontend call to us19.api.mailchimp.com is done by a @mailchimp/mailchimp_marketing, as such targetting /3.0/lists isn't an option. Also after further reading, there is no way to configure CORS with mailchimp API.

So the solution would be to move the use of @mailchimp/mailchimp_marketing on server side instead of having it on client side.