Error header CORS

good morning,

I have a local react application that through axios calls a route on (GET) forestadmin implemented on a middleware.
retrieves some data and makes a post on the forestadmin database.
unfortunately it doesn’t work and gives me the following error:

Blocked multi-origin request (cross-origin): the origin match criterion does not allow reading of the remote resource from https://website.com Reason: missing CORS “Access-Control-Allow-Origin” header.

The forestadmin application is on heroku and the CROSS_ORIGINS variable is present.

you can help me?

Hello @cliosuper,

Is this question somewhat related to the thread you previously opened here? Public route called from outside

I get that you want to have another app make a GET call directly on your ForestAdmin agent?

yes correct I need another site to make a GET call on a public route but also a POST call where I have to register the user.
Currently the GET call is in middleware

obviously the GET works, if I try to make a POST I have that error or if in the get register to the database the user gives the same error as the CORS

If you open the app.js file from your ForestAdmin agent, you will find a allowedOrigins array definition.

Can you try to add the origin of your POST call in this array? Either directly in the app.js file or via the CORS_ORIGIN environment variable.

ok then I try to add the variable on heroku (the forest admin app resides there remotely for staging) the origin POST localhost:3000 since I am developing locally and then I will change with the remote domain.

I tried to insert the variable, on heroku, CORS_ORIGINS = http://localhost:3000
but keep giving me the usual error …
as I said I am calling the endpoint of my forestadmin app from an application in react locally

Hello @cliosuper,

Could we have a diagram of the call requests you are doing?
If I understand correctly, you have a local react app which make requests to your generated forest admin project.
And this project is hosted on heroku, right?

Did you try to make requests call with your local react app and a local generated forest admin project?

The same problem in locally, gives you the example locally.

app react: http://localhost: 3001
make a call to the admin forest app (http://localhost: 3000)

and the error exits:

Blocked multi-origin request (cross-origin): the origin match criterion does not allow the remote resource to be read from http://localhost: 3000/invio-form. Reason: missing CORS “Access-Control-Allow-Origin” header.

in my .env file of my forestadmin app I set the variable:
CORS_ORIGINS = http://localhost:3001

Hi @cliosuper,

Judging by the error, Reason: missing CORS “Access-Control-Allow-Origin” header. is saying that the required header is missing, not that it has an incorrect value.

May I know where you did put your public service (In which file/location)?
Also, if you are trying to call the service from localhost to heroku server, Access-Control-Allow-Origin is required, so that most likely the source of your issue.
Maybe a browser network tabs screenshot on the failing call would help me to better understand the issue here.

Let me know if that helps

Hi jeffladiray, thx for response.

React app code which calls app forest admin on heroku

const configHeader = {
      headers: {
        'Access-Control-Allow-Origin': '*'
      }
    };
    
    axios.get(process.env.REACT_APP_API_FA + '/invio-form', configHeader, { params: {
      firstname: name, email: email
    } })
      .then(res => {
        // redirect to thank you page
        // window.location.href = ThankYouPage;
        
        console.log(res);
        console.log(res.data);
      })

the call is a GET (I had done some tests) which records data on the forest admin db (then I will change it with a POST)

I was referring to the code you added on the forest admin backend, not the React one.
The access Access-Control-Allow-Origin header should be on the service response.

To be more specific, you can take a look on any given request of your forestadmin UI done to your backend.
Depending on where you did put this service on your backend, it might not attach the Access-Control-Allow-Origin.

I’m sorry but I didn’t understand, if I set the variable on heroku where I insert the url of the app that makes the request is not enough?

This is the code forestadmin

const path = require('path');
const models = require('../models');
const superagent = require('superagent');


module.exports = function landingpm(app) {
    app.get('/invio-form', (request, response, next) => {

        const email = request.query['email'];
        const firstname = request.query['name'];

        models.players.findOne({ where: {email: email} })
        .then(function(obj) {
            if(!obj){
                models.players.create({
                    email: email,
                    firstName: firstname, 
                    status: [{name: "1° contatto"}]
                },{ include: [ {model: models.statusList, as: "status" }] }).then(function(pl){
                    superagent 
                    .post(process.env.BASE_URL_SB + '/contacts/')
                    .set('api-key', process.env.API_KEY_SB)
                    .set('Accept', 'application/json')
                    .send({
                        attributes: {FIRSTNAME: firstname, WEBSITE: 'namesite'},
                        email: email, updateEnabled: false
                    })
                    .end((err, res) => {
                        if(err){
                            response.send({error: error});
                        }else{
                            response.send({status: "ok"}); 
                        }
                    });
                })
            }else{
                // Insert only sb
                superagent 
                .post(process.env.BASE_URL_SB + '/contacts')
                .set('api-key', process.env.API_KEY_SB)
                .set('Accept', 'application/json')
                .send({
                    attributes: {FIRSTNAME: firstname, WEBSITE: 'namesite'},
                    email: email, updateEnabled: false
                })
                .end((err, res) => {
                    if(err){
                        response.send({error: err});
                    }else{
                        response.send({status: "ok"}); 
                    }
                });
            }
        });

    });
};


Thanks @cliosuper,

It looks like the missing CORS configuration in the code you shared could be the problem.
It actually depends on the location of this file in your Forest Admin project folder.
Can you share this location to confirm the origin of the issue?

Thanks for your help to dig into this.

this file code resides in the forestadmin middlewares folder

That is not the right place if you want to benefit from the default CORS configuration of your Forest Admin backend.
I think the place to be, for this file, is routes folder (as if you were creating a Smart Action controller, see documentation)

Let me know if it helps.

ok and can I also call it externally to the app from a defined url as it was now?

I guess so yes.
You can try and let us know if you have any issue.

I have created a smart action but how do I reach this route?
this link: http://localhost:3310/forest/actions/invio-form-test
it returns a 401 error

this link:
http://localhost: 3310/actions/invio-form-test
I get the error Cannot GET / actions / send-form-test

This is is code forest file:

const { collection } = require('forest-express-sequelize');

// This file allows you to add to your Forest UI:
// - Smart actions: https://docs.forestadmin.com/documentation/reference-guide/actions/create-and-manage-smart-actions
// - Smart fields: https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields
// - Smart relationships: https://docs.forestadmin.com/documentation/reference-guide/relationships/create-a-smart-relationship
// - Smart segments: https://docs.forestadmin.com/documentation/reference-guide/segments/smart-segments
collection('players', {
  actions: [
    {
      name: "Invio Form Test",
      type: "global"
    }
  ],
  fields: [],
  segments: [],
});

This is the code of route file:

router.get('/actions/invio-form-test', permissionMiddlewareCreator.smartAction(), (req, res) => {
  res.send('ok');
});

Where am I doing wrong?

Hi @cliosuper !
It seems the endpoint that you call is not the right one:

I get the error Cannot GET / actions / send-form-test

You should be calling actions/invio-form-test no ?
You can try to add to use the endpoint option to make it use the right route.

1 Like