How to solve CORS policy problem for Strapi?

Problem about CORS policy : HELP

Description

Hello everyone !

I created a React app using Strapi for backend and I don’t understand how to setup CORS policy.
Strapi is on my online server, and I run React app on my local computer. When I tried to send a request with Axios, there is this problem :

Access to XMLHttpRequest at ‘http address’ 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.

I created the middleware.js file at config folder as it says in the documentation : https://strapi.io/documentation/v3.x/concepts/middlewares.html#configuration-and-activation

module.exports = {
  load: {
    before: ['timer', 'responseTime', 'logger', 'cors', 'responses', 'gzip'],
    after: ['parser', 'router'],
  },
  settings: {
    cors: {
      enabled: true,
      origin: ['*']
    },
  },
};

I’ve looked at all the forums and articles on the subject, I couldn’t solve the problem.

System

  • Node.js version: v15.2.1
  • Strapi version: 3.3.2 (Community)
1 Like

You shouldn’t need this as allowing * is the current default. Generally CORs issues like this come from the frontend sending improper request headers in which Strapi will only respond with what it can support.

If the request headers don’t match the response headers then frontend stacks will generally throw an error like you are seeing. We will need to do know what you are sending to help.

2 Likes

Can you please double check that your app got restarted after the modifications to CORS settings?


Can you open the developer tools in your browser and look at the Network tab when you request your backend from the frontend. The browser should make an OPTIONS request to check if your request is allowed:

If CORS policy works ok, then you should see something like in the screenshot below. Can you check what Response Headers it sent for the OPTIONS request?

1 Like

Strapi currently does not officially support Node v15.*. The recommended version is v14.*

Check the requirements list:

1 Like

Good catch, sunny is correct, you will have issues on node v15

1 Like

Thank you for all your answers, it enlightened me on how Strapi works. I found the solution: it was a simple mistake on my part in the ReactJS part. Indeed, I used the wrong port (80 instead of 1337). I solved this problem yesterday. Thank you! I took the opportunity to use the right version of NodeJS, and listen to everything you said.

1 Like

What is happen when the app works for localhost on firefox but when I built the apk and test it on mi device it returns me an error when it’s trying to connect.

Indeed on my firefox it works fine. The problem is when I try to connect from my phone once the app is compile and run on it.
I am using node v14.15.3. Strapi 3.4.1 installed step by step using strapi documentation.
The only thing I maintain is the API folder.
Anyway, this is the code on my front-end Ionic:

public login(email: string, pass: string) {
    const loginInputData = new LoginInputData();
    loginInputData.identifier = email;
    loginInputData.password = pass;
    const h2 = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json; charset=utf-8',
        'Access-Control-Allow-Origin': '*',
      })
    };
    console.log('Login headers: ', h2.headers.get('Access-Control-Allow-Origin'));
    return this.http.post<UserData>(this.strapiCnx.getLoginStr(), JSON.stringify(loginInputData), h2);
  }

As you can see, it is when I try to login an user. I repeat, this code works on my pc where I am programming the app.

Greetings

I got this from my pc where the connection success perfectly:

How can I see the same on my device (webview)? On Android I got something like “ERROR TypeError: Cannot read property ‘0’ of undefined”

When I searched about this, people said that it is a CORS problem.

In the version 3.0.0 beta xx and before, I solved the problem adding the config to the security.json and adding headers to the front-end. Now, I do what tutorial says and it doesn’t work for me.

It is a mess for me. I am wasting my time right now…

@peteresteris
So from your screenshot on desktop, it seems that you are making the request from localhost:8100 to 192.168.0.50:1337, what about mobile? what addresses are you accessing on it?

That is a good observation. I don’t know how to see the requesting from the device. The code works perfectly from my localhost requesting to my virtual server. Once, on a minor version (<3.0.0) of strapi I could configurate the server and the client, using config/enviroment/… folders and JSON config archives. But, this is not working anymore. I upgrade strapi and configurated middleware.js, but it is not work.
I checked my connection from my device to the server via ping. But, when I tried to access to the server using postboy from the mobile, I obtained an error.

private server = 'http://192.168.0.50'; private port = '1337';

getLoginStr(){
     return this.server + ':' + this.port + '/auth/local';
 }

That way, I construct my address for login to strapi.
I know there is an issue connecting from webview that makes different the origin and strapi looks that like a different source. But, I couldn’t find the solution…

You could try to allow CORS for any host, just to be sure that the problem is caused by cors or you should investigate something else.

./config/middleware.js

module.exports = {
  //...
  settings: {
    cors: {
      origin: ['*'], //allow all
    },
  },
};

You still can create different folders per environment. The folder got renamed from environment to env.

This is the current structure if you want to create different configs per envs:
./config/env/{env}/{filename}

If allowing all hosts doesn’t help, then also try to allow all headers, since they also cause CORS problems:

module.exports = {
  //...
  settings: {
    cors: {
      origin: ['*'], //allow all origins
      headers: ['*'], //allow all headers
    },
  },
};

I tried this solution too, and nothing happened.
I tried with brackets and only ‘*’.

I didn’t know the format of forlders is still being used.
I will put brackets [] on the origin but I tried that before.
How can I see webview console of my device?
How do I know middleware.js is running on my strapi server?

Irdk, that’s not a thing related to Strapi, so I would suggest to google it, there you will find more information on how to debug mobile browser. As I remember there is a thing in Developer tools where you active USB debugging and on your phone you should also activate USB debugging. Then you connect the phone through USB to your PC and it will detect it in the browser. Something like that.

You can run the app in console mode: yarn strapi console, now you can execute real-time commands inside the server, type the following command: strapi.middleware, it will return an object with all the middlewares:

Thanks a lot pal…I didn’t solve the problem but now I have almost a confirmation. I realize a couple of things.
One, the device is sending correctly the request:
Accept: application/json, text/plain, /
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=UTF-8
Referer: http://localhost/
User-Agent: Mozilla/5.0 (Linux; Android 9; Redmi Note 6 Pro Build/PKQ1.180904.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36

Two, the strapi server is refusing the request:
Failed to load the response data

And finally, Strapi is not loading my configuration via middleware.js:

I disable on purpose cors on my middleware.js and checked with yarn strapi console and it still continues enabled.

I don’t know what I am doing bad in this case…

@peteresteris is your code somewhere public I can take a look?

Sorry pal, I recently look your answer. I am not on my computer now.
I am working in ionic and I am using Cordova http installed on capacitor. I know that it is used for web browsers but it is supposed that works with the right strapi cors configuration.
The other way is hardest one. I will have to reprogram all my code making two services. One for browser and other for devices using advanced-native-http and use condition to select one or the other depending on platform.
Or, to use only native-advanced-http and ionic proxy.
:grimacing::slightly_frowning_face::sob: Both ways are hard. I have working we promises and I will have to refactor all my code in order to use observables.

May i know what is the exactly path for this file? Is it
/middlewares/config/middleware.js? I a bit not sure that, it show ./config/midldleware.js in the docs.