【问题标题】:How to set React app and API on same port?如何在同一端口上设置 React 应用程序和 API?
【发布时间】:2018-12-24 07:57:50
【问题描述】:

我有一个 React 应用程序,它通过 API 从单独的数据库中提取数据。

当我在本地运行它时,应用程序是一个端口,而 API 在另一个端口上。

因为当我在应用程序中对 API 进行 AJAX 调用时,我需要包含 API 可以连接的 URL。

如果我对单独的端口进行硬编码(例如,应用程序在 http://localhost:3000 上,API 在 http://localhost:3100 上,使 AJAX url 调用 API http://localhost:3100/api/trusts),它就可以工作。

但是,由于应用程序和 API 位于不同的端口上,我无法将 AJAX url 设为相对路径,因为它错误地将 AJAX 调用发送到 http://localhost:3000/api/trusts 而不是 http://localhost:3100/api/trusts

如何让它们在同一个端口上运行?

谢谢!

这是我的 server.js:

var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var path = require('path');
var app = express();
var router = express.Router();
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

//set our port to either a predetermined port number if you have set it up, or 3001
var port = process.env.PORT || 5656;

//db config
var mongoDB = 'mongodb://XXX:XXX!@XXX.mlab.com:XXX/XXX';
mongoose.connect(mongoDB);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

//body parsing
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// allow cross-browser
app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  next();
});

// handling static assets
app.use(express.static(path.join(__dirname, 'build')));

// api handling
var TrustsSchema = new Schema({
  id: String,
  name: String
});

var Trust = mongoose.model('Trust', TrustsSchema);

const trustRouter = express.Router();

trustRouter
    .get('/', (req,res) => {

      Trust.find(function(err, trusts) {
        if (err) {
          res.send(err);
        }
        res.json(trusts)
      });
    });

app.use('/api/trusts', trustRouter);


//now  we can set the route path & initialize the API
router.get('/', function(req, res) {
  res.json({ message: 'API Initialized!'});
});

app.get('/*', function (req, res) {
   res.sendFile(path.join(__dirname, 'build', 'index.html'));
 });

app.listen(port, function() {
  console.log(`api running on port ${port}`);
});

下面是我试图进行的 AJAX 调用,它不起作用,因为相对路径附加到应用程序的端口(即http://localhost:3000/)而不是 API 的端口(即http://localhost:3100/):

axios.get("/api/trusts")
  .then(res => {
    this.setState({trusts: res.data});
  })
  .catch(console.error);

【问题讨论】:

  • 你不能在同一个端口上同时运行它们。根据您的设置,您可以使用代理将 API 请求重定向到后端服务器。这样您就不需要对 URL 进行硬编码,而是使用 /api/foo 来发出请求。
  • 如果你使用的是webpack-dev-server,你可以使用内置代理将/api/...的请求透明地发送到另一个地址webpack.js.org/configuration/dev-server/#devserver-proxy
  • 我已经尝试设置代理,但它并没有解决我遇到的问题。我已经包含了上面的 AJAX 调用,以提供更多关于我正在尝试做什么的上下文。
  • 你肯定想要代理。它允许您将所有对 /api/trusts 的请求转发到特定端口,例如 http://localhost:3100/api/trusts
  • 您正在使用静态处理程序。您能否从静态目录为 React 应用程序提供服务,在这种情况下,它将知道访问动态请求的正确方法,因为它将来自同一个主机:端口。你如何托管 React 应用程序?

标签: javascript reactjs express


【解决方案1】:

要告诉开发服务器将任何未知请求代理到开发中的 API 服务器,请在您的 package.json 中添加一个代理字段,例如:

"proxy": "http://localhost:4000",

这样,当您在开发中fetch('/api/todos') 时,开发服务器将识别出它不是静态资产,并将您的请求代理到http://localhost:4000/api/todos 作为后备。开发服务器只会尝试将其 Accept 标头中没有 text/html 的请求发送到代理。

“请记住,代理仅在开发中有效(使用 npm start),您需要确保 /api/todos 等 URL 指向生产中的正确内容。”

注意:此功能适用于 react-scripts@0.2.3 及更高版本。

更多详情:https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development

【讨论】:

  • 很抱歉,但我仍然无法正常工作。我已经在 package.json 中包含了代理行,但是当进行 AJAX 调用时,相对路径会附加到应用程序的端口,并且 API 的端口被列为代理。
  • 您的代理是否设置为http://localhost:3100?使用此配置,Request URL 仍应显示:3000,但代理会将请求传递给:3100。如果您还没有重新启动开发服务器,也请尝试重新启动。
  • 谢谢,wdm!我现在可以让它在本地工作,但是当我将它部署到 Heroku 时,我收到了 Invalid Host 错误。我开始了另一个线程寻求帮助:stackoverflow.com/questions/51386191/…(这并不像我希望的那么容易。)
  • 等等,只有开发?没有生产的答案?对不起,但这不是一个很好的答案。当人们为生产而构建时,这会让他们感到困惑。
  • @dylanh724 该问题明确指出环境是本地的。在生产环境中,您可以在 Web 服务器的配置中设置代理。如果您需要与特定生产需求相关的更多详细信息,您可以提出其他问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
相关资源
最近更新 更多