使用快速后端将 create-react-app 部署到 heroku 会在浏览器中返回无效的主机标头

IT技术 reactjs express heroku proxy create-react-app
2021-04-09 04:24:31

标题说明了一切。我在这里构建了一个最小的工作示例:https : //github.com/sehailey/proxytest

我已经尝试过,所以我可能已经数不清了(尽管它们存储在提交中)。我保证,一旦我得到答案,就会跟进询问这个问题的数十个回答线程。

1个回答

看起来他们改变了create-react-app使用代理的方式。取出proxypackage.json然后...

添加这个包:

npm i -S http-proxy-middleware

然后创建一个setupProxy.jsin src

src/setupProxy.js

const proxy = require("http-proxy-middleware");

module.exports = app => {
  app.use(proxy("/api/*", { target: "http://localhost:5000/" }));
};

现在从 React 组件内部,您可以执行以下操作:

源代码/应用程序.js

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";

export default class App extends Component {
  state = {
    message: "",
    error: "",
    eee: "",
    text: ""
  };

  componentDidMount = () => this.fetchAPIMessage();

  fetchAPIMessage = async () => {
    try {
      const res = await fetch(`/api/message`);
      const { message } = await res.json();
      this.setState({ message });
    } catch (err) {
      console.error(err);
    }
  };

  render = () => (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>WELCOME CREATE REACT APP!</p>
        <div className="App-link">{this.state.message}</div>
      </header>
    </div>
  );
}

index.js(我添加npm i -D morgan了一个方便的日志框架——当请求命中 API 时,它会在控制台中显示它)。

const path = require("path");
const express = require("express");
const app = express();
const morgan = require("morgan");

app.use(morgan("tiny")); // logging framework

// Serve our api message
app.get("/api/message", async (req, res, next) => {
  try {
    res.status(201).json({ message: "HELLOOOOO FROM EXPRESS" });
  } catch (err) {
    next(err);
  }
});

if (process.env.NODE_ENV === "production") {
  // Express will serve up production assets
  app.use(express.static("build"));

  // Express will serve up the front-end index.html file if it doesn't recognize the route
  app.get("*", (req, res) =>
    res.sendFile(path.resolve("build", "index.html"))
  );
}

// Choose the port and start the server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Mixing it up on port ${PORT}`));

package.json(用于node提供生产资产——参见“开始”脚本)

{
  "name": "proxytest",
  "version": "0.1.0",
  "private": true,
  "homepage": "https://proxytest2.herokuapp.com/",
  "dependencies": {
    "concurrently": "^4.0.1",
    "express": "^4.16.4",
    "http-proxy-middleware": "^0.19.0",
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-scripts": "2.0.5",
    "serve": "^10.0.2"
  },
  "scripts": {
    "start": "NODE_ENV=production node index.js",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "client": "react-scripts start",
    "server": "nodemon server",
    "eject": "react-scripts eject",
    "dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\"",
    "heroku-postbuild": "npm run build"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

运行时您将在控制台中看到的内容production

m6d@m6d-pc:~/Desktop/proxytest-master$ npm start

> proxytest@0.1.0 start /home/m6d/Desktop/proxytest-master
> NODE_ENV=production node index.js

Mixing it up on port 5000
GET / 200 2057 - 6.339 ms
GET /static/css/main.068b9d02.chunk.css 304 - - 1.790 ms
GET /static/js/1.9a879072.chunk.js 304 - - 0.576 ms
GET /static/js/main.e3ba6603.chunk.js 304 - - 0.605 ms
GET /api/message 201 36 - 4.299 ms
GET /static/media/logo.5d5d9eef.svg 304 - - 0.358 ms

其他注意事项:

  • 确保将您的客户端 src 与 API 分开(例如,将前端 React 应用程序中的所有内容放入一个client包含其自身依赖项文件夹中)。
  • 从您的 API 中删除所有 React 依赖项 package.json
由于我没有您的代码,因此我无法确定您的问题出在哪里。
2021-05-23 04:24:31
因此,我使用 localhost:3000 来托管我的 CRA 客户端,使用 localhost:3001 来托管我的 Express Server。在我的 client/src 文件夹中添加src/setupProxy.js和指向app.use(proxy("/api/*", { target: "http://localhost:3001/" }));目前不起作用。有任何想法吗?
2021-05-25 04:24:31
很棒的答案,干得好,谢谢!我将与其他数十人分享,并希望它可以在未来避免其他人的一些挫折。
2021-06-14 04:24:31
代理应该指向后端。在上面的示例中,后端在端口 5000 ( http://localhost:5000/api) 上提供服务。在生产中,当所有内容都在单个端口上提供服务时,/如果客户端路由共享相同的路由名称,则使用只会干扰客户端路由——这就是为什么我将所有后端路由附加到/api.
2021-06-15 04:24:31
我实际上在 Azure 上遇到了同样的问题:stackoverflow.com/questions/52970371/...
2021-06-19 04:24:31