简体   繁体   中英

Fetch call returns react index.html and chrome gives error Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

I am trying to fetch data from my local express server, and display it with react, but it seems that the index.html of the react app is being returned. If I check the network tab in the console and it shows that there is a fetch request with the name "projects/" and when I hover over it it shows "http://localhost:3000/api/projects". The console indicates that the problem is in line 13 of the react file which is "fetch('/api/projects/')". I've been trying for a while to fix this but can't seem to get it right. Code below

Express:

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

app.use(express.json());

let projects = [
  {
    id: 1,
    title: "project1",
    description: "One - description",
    url: "www.One.com"
  },
  {
    id: 2,
    title: "project2",
    description: "Two - description",
    url: "www.Two.com"
  },
  {
    id: 3,
    title: "project3",
    description: "Three - description",
    url: "www.Three.com"
  }
];

app.get("/api/projects", (req, res) => {
  res.json(projects);
});

const PORT = 5000;
app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

React:

import React from "react";
import "./App.css";

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      projects: []
    };
  }

  componentDidMount() {
    fetch("/api/projects/")
      .then(res => res.json())
      .then(projects =>
        this.setState({ projects }, () =>
          console.log("Projects fetched...", projects)
        )
      );
  }

  render() {
    return (
      <div className="App">
        <h1>Projects</h1>
      </div>
    );
  }
}

export default App;

React package.json:

{
  "name": "my-full-stack-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:5000",
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [">0.2%", "not dead", "not op_mini all"],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Your server is running on port 5000 and the client on port 3000. So, you have to call the api request as fetch('http://localhost:5000/api/projects/')

If you don't specify the full URL, the request will be sent to http://localhost:3000/api/projects

You can also store the base URL in a constant.

import React from 'react';
import './App.css';

const baseUrl = 'http://localhost:5000';

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      projects: []
    }
  }

  componentDidMount() {
    fetch(`${baseUrl}/api/projects/`)
      .then(res => res.json())
      .then(projects => this.setState({ projects }, () => console.log('Projects fetched...', projects)));
  }

  render() {
    return (
      <div className="App">
        <h1>Projects</h1>
      </div>
    );
  }
}

export default App;

Seems it was a cross-origin request. I installed the cors middleware, following the steps in the expressjs documentation, and added it to my express file and used app.use(cors()). Everything works now!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM