4

I am trying to run an application locally which has React/Redux front-end and communicates with a rails api. In my .env file I am referencing the port which is running my api (rails s has it running on port as API_URL 3000) and my react dev server is referenced in HOST running on localhost:3003.

When I go to localhost:3003 and have my react font-end up, I get the following error when i send requests to my api: Bothy me .env files are also pointing at the correct ports on localhost.

XMLHttpRequest cannot load http://localhost:3000/users_company. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3003' is therefore not allowed access. The response had HTTP status code 500.

Any ideas ?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
JohnSnow
  • 6,911
  • 8
  • 23
  • 44

3 Answers3

4

In react applications which are created using create-react-app you can add a proxy in your react application's package.json. Here is an example of this from on of my own projects.

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:8000",
  "dependencies": {
    "@types/jest": "^19.2.3",
    "@types/node": "^7.0.18",
    "@types/react": "^15.0.24",
    "@types/react-dom": "^15.5.0",
    "@types/react-router-dom": "^4.0.4",
    "@types/socket.io": "^1.4.29",
    "@types/socket.io-client": "^1.4.29",
    "axios": "^0.16.1",
    "react": "^15.5.4",
    "react-dom": "^15.5.4",
    "react-router-dom": "^4.1.1",
    "socket.io": "^2.0.1",
    "socket.io-client": "^2.0.1"
  },
  "devDependencies": {
    "react-scripts-ts": "1.4.0"
  },
  "scripts": {
    "start": "react-scripts-ts start",
    "build": "react-scripts-ts build",
    "test": "react-scripts-ts test --env=jsdom",
    "eject": "react-scripts-ts eject"
  }
}

Webpack will take the requests and proxy them to the url specified in the package.json and CORS will be handled for you. Of course this can be done in react applications that were created manually, but this would mean configuring webpack to proxy requests manually as well.

I should also point that now in your code you do not need to write the entire url like http://localhost:8000/api/something/some rather you can just write api/something/some. This is super helpful for deployment of course because now we dont care about the first part of the url which obviously changes from dev to production.

Chaim Friedman
  • 6,124
  • 4
  • 33
  • 61
2

For anyone migrating to this answer who is using Webpack but not Create React App, you can still set up a proxy if you're using webpack-dev-server. This is true for any JavaScript front-end on Webpack, not just React.

For example, I'm running my front-end on localhost:8080 and Rails is on localhost:3000. In your webpack.config.js file in the section where you define devServer:

  devServer: {
    // ...
    // Rails backend runs on localhost:3000
    proxy: {
      '/': {
        target: 'http://localhost:3000',
        secure: false
      }
    }
  },

You can read more about configuration options in the Webpack docs here and in the http-proxy-middleware docs here (the underlying dependency).

Sia
  • 8,894
  • 5
  • 31
  • 50
0

Yes, I suspect this is a CORS thing too, commenting only because it's CORS + Rails specific, not solving in Node.

There's a Gem called rack-cors that lets you set the CORS' Access-Control-Allow-Origin header to the rendered page.

You set up the gem into your Rails middleware chain, and allow from either * (the easiest) or the specific hosts you may see requests from (more secure, but annoying).

There's an excellent blog article on this: Navigating CORS using React and Rails.

You also might consider serving your React app through the asset pipeline (maybe even via git submodules, or just a local symlink, if you want to have your frontend application live in a separate repo from your backend (because please do): react-rails-hot-loader

RyanWilcox
  • 13,890
  • 1
  • 36
  • 60
  • Hey I am using rack-cors and its all set up in my config/applications.rb file but still cors error – JohnSnow Jul 05 '17 at 19:27
  • use curl and see if the CORS headers are returned?? I had this happen to me with rack-cors, I forget what the solution was other than pounding on it for a bit (and I'm away from where I could look...) – RyanWilcox Jul 05 '17 at 19:30