ReactJS API 从 componentDidMount returns index.html 调用作为响应

ReactJS API call from componentDidMount returns index.html as response

我有一个非常简单的 ReactJS 应用程序。我想在页面加载时从我的 API 中获取一些数据。在我的 componentDidMount() 函数中,我调用 getData() 方法来初始化我的应用程序中的状态。当我这样做时,控制台会告诉我:

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

当我检查我的网络选项卡时,我发现我的呼叫的响应是以纯文本形式返回给我的 index.html 页面。我觉得很奇怪。

import React, {Component} from 'react';
import {Router} from "@reach/router";
import Applications from "./Applications";
import Application from "./Application";
import LogIn from "./LogIn";

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            applications: []
        }
    }

    componentDidMount() {
        this.getData();
    }

    //Fetch data from the API and putting it in the state
    async getData() {
        const url = "/api/applications";
        const response = await fetch(url);
        const data = await response.json();
        this.setState({
            applications: data
        })
    }

    // And so on....
}

我不知道为什么会发生这种情况 - 因为当我从 PostMan 给我的 API 打电话时,一切都很好而且很漂亮。数据库的预期响应(与邮递员的电话一起工作):

[
    {
        "_id": "5edfac8b75b2bd3fa477555f",
        "text": "Application for Fullstack Developer",
        "applications": [],
        "__v": 0
    }
]

我收到的回复:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="/manifest.json" />
    <!--
      Notice the use of  in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>Job Applications</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  <script src="/static/js/bundle.js"></script><script src="/static/js/0.chunk.js"></script><script src="/static/js/main.chunk.js"></script></body>
</html>

就这样吧。

const url = "/api/applications";
fetch(url)
    .then(response => response.json())
    .then(data => this.setState({ applications: data }));

希望这会有所帮助。

Aaaa 和 MASSIVE BRAINFART...

当然我的申请没有return任何东西。我的 API 运行 作为我机器上完全不同端口上的一个单独实例。因此,当我想点击 API 时,我必须指定完整的 URL 而不仅仅是 /api/whatever - 在我的情况下,完整的 URL 应该是 http://localhost:8080/api/applications

注意 - 最好的做法是将 URL 的基本部分存储在 .env 文件中,并为其命名,例如 URL_BASE=http://localhost:8080 并将其添加到我的变量中。

let url = process.env.URL_BASE + '/api/applications';

这样,如果您不设置 URL_BASE,您只会得到 URL 前面的空字符串。此结构与 Heroku

等托管服务一起使用