在 Heroku 上使用 React、Axios 访问内部 API [英] Accessing internal API with React, Axios on Heroku

查看:17
本文介绍了在 Heroku 上使用 React、Axios 访问内部 API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个完整的堆栈 React 应用程序,该应用程序使用 Axios 访问其自己的后端 API.在我的本地环境中,以下内容按预期工作,服务器响应 JSON 数据,然后正确呈现.

I am building a full stack React application that accesses its own back end API with Axios. In my local environment, the following works as expected, with the server responding with JSON data, which is then rendered properly.

axios.get('/api/questions/categories')

我部署到Heroku,应用正常启动,连接MongoDB.现在,当发出相同的 GET 请求时,它不会到达后端.当我将来自 Axios 的响应记录到控制台时,它包含页面的实际 HTML,而不是预期的 JSON 对象.

I deployed to Heroku, and the app is launching normally and MongoDB is connected. Now, when the same GET request is made, it is not reaching the back end. When I log the response from Axios to the console, it contains the actual HTML of the page, instead of the JSON object expected.

为了进一步说明,如果我手动输入 'http://localhost:8080/api/questions/category' 在地址栏中显示预期的 JSON 数据.如果我对 Heroku 上的应用程序执行相同操作,我会看到 '#' 附加到 url 并且页面显示没有改变,没有错误消息.这让我认为涉及到 react-router,但我一直无法弄清楚如何/为什么.

For further clarification, if I manually type 'http://localhost:8080/api/questions/categories' in the address bar, the expected JSON data is displayed. If I do the same with the app on Heroku, I see that a '#' is appended to the url and the page display does not change, no error messages. This leads me to think that react-router is involved, but I have not been able to figure out how/why.

我的堆栈:Node、Express、Mongo、React

My stack: Node, Express, Mongo, React

不使用 Redux

使用Axios调用自己的API

Using Axios to call my own API

// Dependencies
var express = require('express');
var path = require('path');
var webpack = require('webpack');
var webpackMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var config = require('./webpack.config.js');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var morgan = require('morgan');

var inDev = process.env.NODE_ENV !== 'production';
var port = inDev ? 8080 : process.env.PORT;
var app = express();

// MIDDLEWARE

if (inDev){
  var compiler = webpack(config);
  var middleware = webpackMiddleware(compiler, {
    publicPath: config.output.publicPath,
    contentBase: 'app',
    stats: {
      colors: true,
      hash: false,
      timings: true,
      chunks: false,
      chunkModules: false,
      modules: false
    }
  });

  app.use(morgan('dev'));
  app.use(middleware);
  app.use(webpackHotMiddleware(compiler));
  app.get('/', function response(req, res) {
    res.write(middleware.fileSystem.readFileSync(path.join(__dirname,     'dist/index.html')));
    res.end();
  });
} else {
  app.use(express.static(__dirname + '/dist'));
  app.get('*', function response(req, res) {
    res.sendFile(path.join(__dirname, 'dist/index.html'));
  });
}

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

app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  res.setHeader('Access-Control-Allow-Methods',     'GET,HEAD,OPTIONS,POST,PUT,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers,  Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method,   Access-Control-Request-Headers');

  //and remove caching so we get the most recent comments
  res.setHeader('Cache-Control', 'no-cache');
  next();
});

// DATABASE

var dbPath = inDev ? 'mongodb://localhost/quizMe' :     'mongodb://heroku_pmjl5579:c28cf07fpf05uus13ipjeur5s7@ds143000.mlab.com:43000/heroku_pmjl5579';

mongoose.connect(dbPath);

// ROUTING / API

// var indexRoute = require('./routes/index');
var questionsRoute = require('./routes/api/questions');
// app.use('/', indexRoute);
app.use('/api/questions', questionsRoute);

app.listen(port, function(){
  console.log('Express server up on ' + port);
});

感谢您的帮助!

推荐答案

大多数单页应用程序将所有请求路由到根路径并让前端路由器接管.我怀疑这就是您的应用发生的情况.

Most single page applications route all requests to the root path and let the front end router take over. I suspect that is what is happening to your app.

您的后端代码或任何服务器配置代码中是否有任何形式的请求重定向逻辑?

Do you have any form of requests redirection logic in your back end code or any server configuration code?

您可以做的是将一些您不希望前端路由接管的路径列入白名单,例如那些以/api 开头的路径.在此处粘贴您的服务器端配置会有所帮助.

What you can do is to whitelist some paths that you don't want front end routing to take over, such as those that start with /api. Pasting your server side config here will be helpful.

在您的服务器配置中,当 inDevfalse 时,您有一个 app.get('*', ...)捕获所有请求并使用静态单页应用程序进行响应.因此 API 请求也会给出相同的响应.您将需要重构您的路由以匹配通配符 * 之前的 /api.可以在此处

In your server config, when inDev is false, you have a app.get('*', ...) that catches all requests and responds with the static single page app. Hence API requests will also give the same response. You will need to restructure your routes to match /api before the wildcard *. Some examples can be found here

这篇关于在 Heroku 上使用 React、Axios 访问内部 API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆