10

I used create-react-app to build my react app. This app does a POST call on another API (elasticsearch), hosted on a different server (not owned/managed by me). So once the user enters the data in the form, onSubmit basically calls getResponse() method that makes the call. Initialize client:

let client = new elasticsearch.Client({
    host: "https://{cred.user}:{cred.pass}@@servername.domain:11121",
    log: "trace",
});

API query:

getResponse = () => {
        client
          .search({
            index: 'custom_index_1',
            body: {
                query: {
                    match: {"data": this.state.data}
                },
            }
        },function(error, response, status) {
            if (error) {
                const errorMessage= {error};
                console.log(errorMessage);
            }
            else {
                this.setState({results: response.hits.hits});
                console.log(this.state.results);
            }
        });
    }

But I'm getting the CORS error as follows:

Failed to load resource: the server responded with a status of 403 (Forbidden)
localhost/:1 Access to XMLHttpRequest at 'https://servername.domain:11121/' 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.console.js:40 
WARNING: 2019-11-21T07:54:32Z No living connections

After reading in SO about the same issue, I found that using the cors npm module can fix this issue (at least in development). But I do not understand where do I put this code:

var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())

OR

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

My questions are as follows: 1. Where do I add this code above? in my react app's app.js? If yes, can someone give me an example please. I am using something like this:

import statements
class App extends Component {
 <code>
}
export default App;
  1. If this code is to be added to some other file then which file? Is it server.js? If yes, where do I find this? I'm using Windows 7. Node is installed in a customer directory: C:\MYSW\NodeJs\12.1.0. I see some server.js in here: C:\Users\user1\Scratch\node\myreact_ui\node_modules\react-dom\server.js, but is it the right file

  2. Please give me a sample of how the code is added and where exactly in the file. I am new to React and Node so I do not know much about the internals. I'v been stuck here for days now and really need some help. Thanks.

Everywhere it says, add this code and it work, no one mentions where do I add it and how? Any help appreciated.

reactjs_user
  • 159
  • 1
  • 2
  • 8

4 Answers4

9

Add below code in node js API

  app.use(function(req, res, next) {
     res.header("Access-Control-Allow-Origin", "*");
     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
     next();
});

or

//allow OPTIONS on all resources
app.options('*', cors())
Suhag Lapani
  • 655
  • 10
  • 18
6

You need to set up a proxy server for API requests - https://create-react-app.dev/docs/proxying-api-requests-in-development/

I do not fully understand the details for Elastic server, but you can put the Express code into src/server.js file, inspired by https://stackoverflow.com/a/20539239/1176601:

var express = require('express')
var request = require('request')
var cors = require('cors')
var app = express()

app.use(cors())

app.use('/', function(req, res) {
  var url = 'https://' +
    req.get('host').replace('localhost:80', 'servername.domain:11121') + 
    req.url
  req.pipe(request({ qs:req.query, uri: url })).pipe(res);
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

update package.json

"scripts": {
   ...
   "server": "node src/server.js"
},
"proxy": "http://localhost:80"

Modify your client:

let client = new elasticsearch.Client({
    host: "{cred.user}:{cred.pass}@@localhost:80",
    log: "trace",
});

And start it by npm run server (before or after npm start, e.g. in a separate terminal).

Before the first start, you will need to install all required modules, npm i -D express request cors.

Aprillion
  • 21,510
  • 5
  • 55
  • 89
  • I don't have the src/server.js. Should I create a new file add that code in the file and then make changes to package.json and run it on a different terminal using npm run server? – reactjs_user Nov 21 '19 at 10:25
  • Thanks, trying right now. Will update shortly. Appreciate your quick help!! – reactjs_user Nov 21 '19 at 10:33
  • I made the changes and ran " npm run server" which threw this error: error code ELIFECYCLE error errno1 npm ERR! Failed at the reportingportal_ui@0.1.0 server script. npm ERR! This is probably not a problem with npm. There is likely additional log ging output above. – reactjs_user Nov 21 '19 at 10:38
  • ah, do you only have 1 "server" script in your package.json? if yes, what was the *additional output above*? if not, rename both the file and the command to `dev_server`... – Aprillion Nov 21 '19 at 10:42
  • did you `npm i -D express cors` before running it? – Aprillion Nov 21 '19 at 10:44
  • Well, it says cannot find module 'cors', but I had installed it earlier using npm install -g cors --save. Error message: internal/modules/cjs/loader.js:613 throw err; ^ Error: Cannot find module 'cors' So I re-ran npm install cors --save, but it errored out with: npm ERR! code ETARGET npm ERR! notarget No matching version found for @hapi/hoek@8.2.5 npm ERR! notarget In most cases you or one of your dependencies are requesting npm ERR! notarget a package version that doesn't exist. npm ERR! notarget npm ERR! notarget It was specified as a dependency of '@hapi/joi' – reactjs_user Nov 21 '19 at 10:51
  • hm, looks like a problem with `cors` itself pointing to a wrong dependency, I won't be able to help with that, I would suggest to search and/or ask a separate question about the installation – Aprillion Nov 21 '19 at 10:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202795/discussion-between-reactjs-user-and-aprillion). – reactjs_user Nov 21 '19 at 11:46
2

You should add that to the file where you configure the server you are using. If you were using express you would add that to the server.js file you are talking about but it seems you have an elasticsearch server and a react app so you do not have a node.js backend.

You probably will have to include a cors configuration in the elasticsearch server.

Pedro Rio
  • 66
  • 1
  • 6
  • create-react-app on localhost:3000 => he is using webpack-dev-server – Aprillion Nov 21 '19 at 10:30
  • There is some explanation here: https://daveceddia.com/access-control-allow-origin-cors-errors-in-react-express/, but I understand the problem, I am just trying to figure out how to best solve it when I can't touch/change the elasticsearch APIs. – reactjs_user Nov 21 '19 at 10:32
0

This will solve the issue,

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*')
    res.header('Access-Control-Allow-Headers', '*')
    next()
})

You can replace * for specific domain as well.

Shubham Sarda
  • 539
  • 5
  • 10