CORS blocking API call from Dockerized React project

10,114

Solution 1

Your node application should support CORS, if you are using express, you should add the following lines in the app.js file

const cors = require('cors'); app.use(cors()); app.options('*', cors());

Solution 2

'Access-Control-Allow-Origin' header contains the invalid value '"http://172.28.1.1:3000"'

  1. It looks like the quotes are being treated as being part of the environment variable value:

environment: - CORSHEADER="http://172.28.1.1:3000" - PROXY=true

Should be:

environment: CORSHEADER: "http://172.28.1.1:3000" PROXY: true

(though, you can escape it too: docker-compose - how to escape environment variables)

  1. The docker-compose.yml you shared appears to be malformed:

environment: - NODE_ENV=development depends_on: - restaurant-data-service

The indentation at this bit is inconsistent with the rest of the web-ui-service keys. It does not parse correctly, but this may have been an accident?

Share:
10,114
Timothy Hawkins
Author by

Timothy Hawkins

Updated on June 04, 2022

Comments

  • Timothy Hawkins
    Timothy Hawkins almost 2 years

    I'm having issues running a detached dockerized React app that makes Restful calls to a dockerized Node.js microservice. The issues that I'm having is that the requests are blocked by the CORS policy with the following error:

    Access to XMLHttpRequest at 'http://localhost:3001/api/restaurants/' from origin 'http://localhost:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains the invalid value '"http://172.28.1.1:3000"'.

    There is a url environment variable the I use to set the accepted cors header when the container is run up. I have used the same technique to make requests between 2 headless apps. Is there something about React that means this will not work?

    I have tried setting the IP addresses in the docker-compose in order to pass in as the CORSHEADER env variable. I've added the relevant code below.

    docker-compose.yml

    version: '3'
    
    services:
      web-ui-service:
        container_name: web-ui-service
        build:
          context: .
          dockerfile: Dockerfile
        volumes:
          - '.:/usr/src/app'
          - '/usr/src/app/node_modules'
        ports:
          - '3000:3000'
        depends_on:
          - restaurant-data-service
        networks:
          vegitable_net:
            ipv4_address: 172.29.1.1
    
      restaurant-data-service:
        image: timhaydenhawkins/restaurant-data-service
        environment:
          CORSHEADER: "http://172.29.1.1:3000"
        ports:
          - 3001:3001
        networks:
          vegitable_net:
            ipv4_address: 172.29.1.2
    
    networks:
      vegitable_net:
        ipam:
          driver: default
          config:
            - subnet: 172.29.0.0/16
    

    Cors header setting in restaurant-data-service

    module.exports = function (req, res, next) {
      res.setHeader('Access-Control-Allow-Origin', process.env.CORSHEADER);
      res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, 
    DELETE');
      res.setHeader('Access-Control-Allow-Headers', 'X-Requested- 
    With,content-type');
      res.setHeader('Access-Control-Allow-Credentials', true);
      next();
    }
    

    This techniques has worked fine in headless apps in containers but having real issues with it working for React. Any ideas?

  • Timothy Hawkins
    Timothy Hawkins over 5 years
    I've changed the environment variable to the format you've and it's in single quotes now. Still getting the Cors error though. I think the indentation issue was from pasting the code in SO, it's correct in my file
  • Ian
    Ian over 5 years
    Mind sharing the current state of things? (code / config that is, and the CORS error)
  • Timothy Hawkins
    Timothy Hawkins over 5 years
    i've edited the original question to the current state
  • Ian
    Ian over 5 years
    It doesn't look too happy with the value it is getting from the environment. It is not being parsed correctly for whatever reason. I would try hardcoding the value. I assume you are not using Webpack by any chance for restaurant-data-service ? Apart from that, I believe you should also be setting your origin as http://localhost:3000.