CORS 阻止来自 Dockerized React 项目的 API 调用

Posted

技术标签:

【中文标题】CORS 阻止来自 Dockerized React 项目的 API 调用【英文标题】:CORS blocking API call from Dockerized React project 【发布时间】:2019-05-21 01:20:42 【问题描述】:

我在运行分离的 dockerized React 应用程序时遇到问题,该应用程序对 dockerized Node.js 微服务进行 Restful 调用。我遇到的问题是请求被 CORS 策略阻止,并出现以下错误:

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"'.

当容器运行时,我使用一个 url 环境变量来设置接受的 cors 标头。我使用相同的技术在 2 个无头应用程序之间发出请求。 React 有什么东西意味着这不起作用吗?

我尝试在 docker-compose 中设置 IP 地址,以便作为 CORSHEADER env 变量传入。我在下面添加了相关代码。

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 标头设置

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();

这种技术在容器中的无头应用程序中运行良好,但在 React 中运行时存在实际问题。有什么想法吗?

【问题讨论】:

api中的环境变量是否为CORS头设置正确? 作为测试只检查res.setHeader('Access-Control-Allow-Origin', '*'); 是否有效? 是的,使用 '*' 可以正常工作,并且环境变量正在正确传递 【参考方案1】:

你的节点应用应该支持 CORS,如果你使用 express,你应该 在 app.js 文件中添加以下行

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

【讨论】:

【参考方案2】:

'Access-Control-Allow-Origin' 标头包含无效值 '"http://172.28.1.1:3000"'

    看起来引号被视为环境变量值的一部分:

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

应该是:

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

(不过,你也可以逃避它:docker-compose - how to escape environment variables)

    您分享的docker-compose.yml 格式似乎有误:

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

该位的缩进与web-ui-service 的其余部分不一致。它没有正确解析,但这可能是一个意外?

【讨论】:

我已将环境变量更改为您的格式,现在它是单引号。尽管如此,仍然会出现 Cors 错误。我认为缩进问题来​​自将代码粘贴到 SO 中,在我的文件中是正确的 介意分享当前的状态吗? (即代码/配置,以及CORS错误) 我已将原始问题编辑为当前状态 它看起来对从环境中获得的价值不太满意。无论出于何种原因,它都没有被正确解析。我会尝试对值进行硬编码。我假设您没有任何机会使用 Webpack restaurant-data-service ?除此之外,我相信您还应该将您的来源设置为http://localhost:3000

以上是关于CORS 阻止来自 Dockerized React 项目的 API 调用的主要内容,如果未能解决你的问题,请参考以下文章

来自“http://localhost:8000”的 Laravel 8 已被 CORS 策略阻止

Angular 6 + Spring Boot:错误:“来自原点 'http://localhost:4200' 已被 CORS 策略阻止”

来自 Vue 应用程序的发布请求被 CORS 策略阻止

来自rest api的keycloak登录已被CORS阻止

被 CORS 策略阻止 - 来自 Django 应用程序的 S3 存储桶访问

使用反应返回 405 错误获取快速后端(来自原点'null'已被 CORS 策略阻止:对预检等的响应......)