带有axios的MERN堆栈,响应对象返回html而不是json [英] MERN stack with axios, response object returns html instead of json

查看:84
本文介绍了带有axios的MERN堆栈,响应对象返回html而不是json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我要设置一个为期5天的天气预报网络应用程序,以练习使用MERN堆栈与API进行交互.我正在使用Axios.js发送和响应请求;为确保后端工作正常,在开始与API通信之前,我首先开始进行构建.但是,我在前端设置的按钮(向我的服务器发送获取json数据的get请求)总是返回一个带有response.data的响应对象,其值为:

So I'm setting up a 5 day weather forecast web app for practice interacting with APIs using the MERN stack. I'm using Axios.js to send and respond to requests; to make sure I have my back-end working, I started building that out first before starting to communicate with the API. However, the button I have set up on the front-end (which sends a get request to my server for json data) always returns a response object with response.data having the value of:

RESPONSE: <!doctype html>
<html>
<head>
    <meta name="viewport" charset="UTF-8" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <div id="app"></div>
    <script src="./dist/bundle.js"></script>
</body>
</html>

代替

RESPONSE: "hello there!"

对于如下所示的JavaScript:

for a JavaScript that looks like:

{data: "hello there!"}

我知道我在发送和接收这些请求时可能会丢失一个步骤,但是在对此进行了研究之后,我仍然不确定为什么我没有收到预期的结果.我的文件设置如下:

I know I'm probably missing a step when sending and receiving these requests, but after doing research into this I'm still not sure why I'm not receiving the expected result. My files are set up like this:

-weather_forcast
  -client
    -src
      -components(empty)
      app.jsx
  -public
    -dist
      bundle.js
    index.html
  -server
    -routes
      routes.js
    index.js
  package.json
  webpack.config.js

当前其中包含代码的文件的内容为:

The contents of the files that currently have code in them are:

app.jsx

    import React, {Component} from 'react';
    import ReactDOM, {render} from 'react-dom';
    import axios from 'axios';
    // import daysOfWeek from './daysOfWeek.jsx';

    class App extends Component {
      constructor() {
          super();
          this.state = {
          }
          this.getData = this.getData.bind(this);
      }

      getData() {
          axios.get('/')
          .then((response) => {
              console.log("RESPONSE:", response.data);
          })
          .catch((error) => {
              console.log(error);
          })
      }

      render() {
          return(
              <div>
                  <button onClick={this.getData}>Hello world</button>
              </div>
          )
      }
  }

  render(<App/>, document.getElementById('app'));

index.html

index.html

<!doctype html>
<html>
    <head>
        <meta name="viewport" charset="UTF-8" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div id="app"></div>
        <script src="./dist/bundle.js"></script>
    </body>
</html>

routes.js

routes.js

let express = require('express');
let router = express.Router();

router.get('/', (req, res) => {
    res.send({data:'hello there!'});
});

module.exports = router;

index.js

const express = require('express');
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const router = require('./routes/routes.js');
const app = express();
let port = 8000;

app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../public')));

app.use('/', router);

app.listen(port, () => {
  console.log(`express is listening on port ${port}`);
});

webpack.config.js

webpack.config.js

const path = require('path');
const SRC_DIR = path.join(__dirname, '/client/src');
const DIST_DIR = path.join(__dirname, '/public/dist');

module.exports = {
    entry: `${SRC_DIR}/app.jsx`,
    output: {
        filename: 'bundle.js',
        path: DIST_DIR
    },
    module: {
        rules: [
            {
                test: /\.jsx?/,
                include: SRC_DIR,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env', '@babel/preset-react']
                    }
                }
            }
        ]
    }
}

在添加"routes"文件夹并像这样设置index.js文件之前,同样会出现同样的问题:

The same problem presents itself before I added the "routes" folder and had set up my index.js file like this:

const express = require('express');
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const router = require('./routes/routes.js');
const app = express();
let port = 8000;

app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../public')));

app.get('/', (req, res) => {
  res.send({data: "hello there!"});
);

app.listen(port, () => {
  console.log(`express is listening on port ${port}`);
});

任何帮助将不胜感激!我似乎无法将json对象作为数据获取到前端,但是我不确定此设置中缺少的内容.

Any help would be greatly appreciated! I can't seem to get my json object to the front end as data, but I'm not sure what I'm missing from this set up.

推荐答案

您收到的响应似乎表明开发服务器正在为您提供react应用程序(请注意以下行:< script src =./dist/bundle.js"></script> ).

The response you're getting seems to indicate the dev server is serving you the react application (note the line: <script src="./dist/bundle.js"></script>).

当您在不同端口(例如webpack开发服务器和Express应用程序)上同时运行两个服务器时,您可以选择几种方法来处理它们.

When you're running two servers simultaneously on different ports (ex webpack dev server and your express app), you have a few options to handle them.

1)CORS 向您的另一台服务器发送请求,并提供其完整地址:

1) CORS Make a request to your other server with its full address:

"http://localhost:8000/<path>"

通常不建议这样做,除非您的服务器要与React应用程序完全分开并允许CORS.鉴于服务器和客户端都存在于同一个存储库中,看来您将希望服务器也为您的React Application提供服务.

This is generally not recommended unless your server is meant to be completely separate from your React application and allows CORS. Given that both server and client exist in the same repository, it seems that you're going to want your server to serve your React Application as well.

2)代理请求

查看文档以获取更多信息

Webpack使您能够代理服务器请求.如果您在开发中使用其他端口,但是服务器和React应用程序将在生产环境中一起使用,这将很有用.在您的 webpack.config.js 中,您可以执行以下操作:

Webpack gives you the ability to proxy server requests. This is useful if you're using a different port in development, but your server and react app will sit together in production. In your webpack.config.js you can do the following:

webpack.config.js:

module.exports = {
  // prior rules
  module: {
    // module rule followed by comma
  },
  devServer: {
    proxy: {
      "/api": "http://localhost:8000"
    }
  }
}

在您的快递服务器中,为每个请求附加"api",如下所示:/api/< path>

In your express server, append each request with 'api' like this: /api/<path>

路由:

app.use('/api', router);

app.jsx

getData() {
  axios.get('/api')
  .then((response) => {
    console.log("RESPONSE:", response.data);
  })
  .catch((error) => {
    console.log(error);
  })
}

未来

最终,您可能希望"/" 发送React应用程序,而不是使用纯静态方法.

Eventually, you may want "/" to send the React application, instead of using a purely static approach.

在快递应用中,您可以执行以下操作:

In your express app, you can do something like this:

  // serve index.html
  const path = require('path')
  app.get('*', (req, res) => {
    res.sendFile(path.resolve('<PATH TO BUILT APP index.html>')) 
  })

* 是以前未定义的任何请求",这意味着您应该在所有api路径之后定义此 ..这样,除非发出/api/....请求,否则您的应用将得到响应.这样做的真正好处(在我看来)是,所有与服务器路由不匹配的请求都在React应用程序中处理.

The * is "any request not previously defined", meaning you should define this after all of your api routes. This way, you're react app is served unless a /api/.... request is made. The real advantage (in my opinion) of doing something like this is that all requests that do not match a server route are handled in the React application.

这篇关于带有axios的MERN堆栈,响应对象返回html而不是json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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