Azure 上的 React + Express:无效的主机标头

IT技术 reactjs azure express docker
2021-05-20 19:18:01

错误

部署到具有多容器支持的 Azure Web 应用程序时,我收到来自https://mysite.azurewebsites.com“无效主机标头”消息

本地设置

这运行良好。

我有两个 Docker 容器:client一个 React 应用程序和server一个托管我的 API 的 Express 应用程序。我正在使用代理将我的 API 托管在server.

client's package.json 我已经定义:

"proxy": "http://localhost:3001"

我使用以下 docker compose 文件在本地构建。

version: '2.1'

services:
  server:
    build: ./server
    expose:
      - ${APP_SERVER_PORT}
    environment:
      API_HOST: ${API_HOST}
      APP_SERVER_PORT: ${APP_SERVER_PORT}
    ports: 
      - ${APP_SERVER_PORT}:${APP_SERVER_PORT}
    volumes: 
      - ./server/src:/app/project-server/src
    command: npm start

  client: 
    build: ./client
    environment: 
      - REACT_APP_PORT=${REACT_APP_PORT}
    expose:
      - ${REACT_APP_PORT}
    ports:
      - ${REACT_APP_PORT}:${REACT_APP_PORT}
    volumes:
      - ./client/src:/app/project-client/src
      - ./client/public:/app/project-client/public
    links:
      - server
    command: npm start

一切运行良好。

在 Azure 上

部署到 Azure 时,我有以下内容。clientserver图像已存储在 Azure 容器注册表中。它们似乎从日志中加载得很好。

在我的应用服务 > 容器设置中,我正在从 Azure 容器注册表 (ACR) 加载图像,并且我正在使用以下配置 (Docker compose) 文件。

version: '2.1'

services:
  client: 
    image: <clientimage>.azurecr.io/clientimage:v1
    build: ./client
    expose:
      - 3000
    ports:
      - 3000:3000
    command: npm start

  server:
    image: <serverimage>.azurecr.io/<serverimage>:v1
    build: ./server
    expose:
      - 3001
    ports: 
      - 3001:3001
    command: npm start

我还在应用程序设置中定义:

WEBSITES_PORT 为 3000。

这导致我的网站出现错误“无效的主机标头”

我尝试过的事情

• 从 中的static文件夹提供应用程序server这是因为它为应用程序提供服务,但它弄乱了我的身份验证。我需要能够提供来自clientApp.js的静态部分,并与我的 Express API 通信以进行数据库调用和身份验证。

• 在我的 docker-compose 文件中将前端绑定到:

ports:
 - 3000:80

• 一些其他端口组合,但没有运气。

另外,我认为这与基于此 repoproxyinclient的 package.json 有关

任何帮助将不胜感激!

更新

这是代理设置。

这在一定程度上解决了它。通过删除"proxy": "http://localhost:3001"我可以加载网站,但问题中的建议答案对我不起作用。即我现在无法访问我的 API。

2个回答

azure以前从未使用过,我也不使用代理(由于其随机连接问题),但是如果您的应用程序基本上正在运行express,则可以使用cors(作为一个方面说明,这是比较常见的运行在您的Express服务器50003001)。

我首先设置一个env/config.js文件夹和文件,如下所示:

module.exports = {
  development: {
    database: 'mongodb://localhost/boilerplate-dev-db',
    port: 5000,
    portal: 'http://localhost:3000',
  },
  production: {
    database: 'mongodb://localhost/boilerplate-prod-db',
    port: 5000,
    portal: 'http://example.com',
  },
  staging: {
    database: 'mongodb://localhost/boilerplate-staging-db',
    port: 5000,
    portal: 'http://localhost:3000',
  }
};

然后,根据环境,我可以cors在我定义 express 中间件的地方实现

const cors = require('cors');
const config = require('./path/to/env/config.js');
const env = process.env.NODE_ENV;

app.use(
    cors({
      credentials: true,
      origin: config[env].portal,
    }),
  );

请注意门户和AJAX请求必须具有匹配的主机名。例如,如果我的应用程序托管在 上http://example.com,则我的前端 API 请求必须向http://example.com/api/(不是http://localhost:3000/api/——单击此处查看我如何为我的网站实现它)发出请求,并且portalenv 必须与主机名匹配http://example.com在运行多个环境时,这种设置是灵活且必要的。

或者,如果您使用的是create-react-app,则只需弹出您的应用程序并生产配置中实现代理即可webpack

或者将您的应用程序迁移到我的fullstack 样板,它实现了cors上面示例。

因此,我最终不得不离开容器,并在更多典型的 MERN 架构中提供 React 应用程序,其中 Express 服务器托管来自静态构建文件夹的 React 应用程序。我使用 PassportJS 设置了一些路由来处理我的身份验证。

不是我喜欢的解决方案,我更喜欢使用容器,但这有效。希望这能指出有人朝着正确的方向前进!