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

Posted

技术标签:

【中文标题】Azure 上的 React + Express:无效的主机标头【英文标题】:React + Express on Azure: Invalid Host Header 【发布时间】:2019-03-28 22:48:20 【问题描述】:

错误

在部署到支持多容器的 Azure Web 应用时,我收到来自https://mysite.azurewebsites.com

“Invalid Host Header” 消息

本地设置

运行良好。

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

client的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。

这会导致我的网站出现错误“Invalid Host Header”

我尝试过的事情

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

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

ports:
 - 3000:80

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

另外,我认为这与基于this repo 的client 的package.json 中的proxy 有关

任何帮助将不胜感激!

更新

这是代理设置。

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

【问题讨论】:

【参考方案1】:

以前从未使用过azure,我也没有使用代理(由于它的random connection issues),但如果您的应用程序基本上运行express,您可以使用cors。 (附带说明一下,在 5000 上运行 express 服务器比在 3001 上运行更常见。)

我首先设置了一个 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

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/ -- click here 以查看我如何为我的网站实现它),并且portal env 必须与主机名 http://example.com 匹配。在运行多个环境时,此设置是灵活且必要的。

或者,如果您使用的是create-react-app,那么只需弹出您的应用程序并在webpack 生产配置中实现proxy。

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

【讨论】:

感谢您的回复!我仍在探索这里的选项,所以当我有一个可行的解决方案时我会发布。 也许这是另一种解决方案:***.com/questions/43619644/…【参考方案2】:

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

不是我喜欢的解决方案,我更喜欢使用容器,但这可行。希望这能指出正确的方向!

【讨论】:

以上是关于Azure 上的 React + Express:无效的主机标头的主要内容,如果未能解决你的问题,请参考以下文章

跨域会话 Cookie(Heroku 上的 Express API + Netlify 上的 React App)

服务器上的 Express 静态文件未正确加载但 React 前端加载正确?

AWS Cognito 可以在 EB 上的 Node/Express/React 应用程序中使用吗?

如何读取通过服务器端 (node-express) 上的 Passport 设置的客户端 (react) cookie?

如何在 azure 网站上的 react 应用程序中替换 %PUBLIC_URL%

通过重定向将数据从 Express 发送到 React