javascript - 在 Heroku 部署后,React 客户端在指定本地主机时因 Axios 而失败

标签 javascript node.js reactjs http axios

我有一个 React 客户端和一个 NODE.JS 服务器。

客户端在端口 3000 上,服务器在 5000 上。

当我从客户端发出请求时,它看起来像这样:

import axios from "axios";
const axiosInstance = axios.create({
baseURL: "http://localhost:5000"
});

try {
const res = await axiosInstance.post("/api/myRoute", ....);

... more code 
}


catch(...) { 

}

问题是,当我将应用程序上传到 Heroku 时,即使我在 server.js 中使用了 Axios 请求,客户端也会收到 404。 , process.env.PORT :

  const PORT = process.env.PORT || 5000;
  app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

我们如何在不指定 localhost 的情况下在 Heroku 上使用 Axios作为 baseUrl

最佳答案

在开发中,当你转到 localhost:3000 时,你会访问 create-react-app 脚本为你启动的开发服务器 npm start。该服务器然后将您应用的开发包发送到您的浏览器。

您还将为您的 api localhost:5000 启动第二个服务器。这是您的 React 应用程序(现在在浏览器中运行)向其发出本地 api 请求的服务器。

根据您的设置,您(可能)不会有 2 个服务器在生产环境中运行。当有一个请求未被您的 api 路由处理时,您将让您的 Node/express 后端为您的构建文件提供服务(因此很可能是客户端路由)

假设项目结构如下:

-> MyCoolApp
  -> index.js // express server
  -> client // create-react-app application
     -> src
        -> index.js
        -> setupProxy.js

首先设置http-proxy-middleware,以便在开发和生产中使用以相同的方式从您的客户端应用程序向您的服务器发出api请求axios.get('/api/route')

// place in src with index.js no need to import anywhere
const proxy = require('http-proxy-middleware')

module.exports = function(app) {
    // add other server routes to path array
    app.use(proxy(['/api' ], { target: 'http://localhost:5000' }));
}

下一步 设置您的服务器 index.js,使其在生产/暂存和开发中表现不同(假设您使用的是 express):

const express = require('express');
const app = express();

require('./routes')(app); //these are your api routes

//Non api requests in production
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
    // Add production middleware such as redirecting to https

    // Express will serve up production assets i.e. main.js
    app.use(express.static(__dirname + '/client/build'));
    // If Express doesn't recognize route serve index.html
    const path = require('path');
    app.get('*', (req, res) => {
        res.sendFile(
            path.resolve(__dirname, 'client', 'build', 'index.html')
        );
    });
}

//start server
const PORT = process.env.PORT || 5000; //Heroku sets port dynamically
app.listen(PORT, () => {
    console.log('listening...');
}).on('error', err => {
    console.log(`Error Code: ${err.code}`);
});

最后 当 Heroku 完成根依赖项的安装后,它将运行一个名为 heroku-postbuild 的脚本,您可以指示 heroku 安装您的客户端依赖项并构建您的生产 React应用

在你的服务器 package.json 添加/修改这些脚本:

"scripts": {
    "start": "node index.js",
    "server": "node index.js",
    "client": "npm run start --prefix client",
    "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
  },

这最后一部分很有帮助,因为 Heroku 是基于 git 的,将构建目录/文件提交到 git 是不好的做法(如果你在本地保持构建!)

此外,Heroku 默认情况下仅安装生产依赖项(不安装任何开发依赖项),如果这是所需的行为,您可以省略 NPM_CONFIG_PRODUCTION=false

关于javascript - 在 Heroku 部署后,React 客户端在指定本地主机时因 Axios 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58582785/

相关文章:

javascript - Cheerio 和 Gifv 问题

javascript - 添加表行时 react 'this'未定义

reactjs - React Native - 退出应用程序时调用方法

javascript - 按钮 onClick 方法在 react 应用程序中不起作用

javascript - Play 2.0.1 并设置 Access-Control-Allow-Origin

javascript - 在 d3 中发送 POST 请求(使用 d3-fetch)

javascript ctypes 字符串转无符号字符

javascript - 解析来自 Socket 的 HTTP 消息

javascript - 如何在javascript中向根类对象添加新方法?

javascript - 如何仅通过一个 Jest 配置文件/设置使用多个 Jest 预设?