繁体   English   中英

无法在生产中从 Express 获得 JSON 响应

[英]Unable to get JSON response from Express in production

在开发模式下,react 和 express 完美连接,我可以从后端获取数据。 但是,在生产模式下使用它们时,我的状态为 200,但无法从 express 获得 json 响应。

我收到此错误:

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

后端文件是这样的:

const express = require('express');
const bodyParser = require("body-parser");
const cors = require("cors");
const path = require("path");
const helmet = require("helmet");
const compression = require("compression");

if(process.env.NODE_ENV !== "production") require('dotenv').config();

const app = express();

//middlewares
app.use(helmet());
app.use(compression());
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));


// serve the react app files in production
if(process.env.NODE_ENV === "production") {
    app.use(express.static(path.join(__dirname, "client/build")));

    app.get("*", (req, res) => {
        res.sendFile(path.join(__dirname, "client/build", "index.html"))
    })
}

//port
const port = process.env.PORT || 5000;
app.listen(port, error => {
    if(error) throw error;
    console.log(`Backend is running on localhost:${port}`);
});

// connection route
app.get("/express", (req, res) => res.json({express: "YOUR EXPRESS BACKEND IS CONNECTED"}));

后端 package.json:

{
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "engines": {
    "node": "12.19.0",
    "npm": "6.14.8"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon server.js",
    "mainstart": "concurrently --kill-others-on-fail \"npm start\" \"cd client && yarn start\""
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/g4rry420/armourLine.git"
  },
  "author": "Gurkiran Singh",
  "license": "ISC",
  "bugs": {
    "url": ""
  },
  "homepage": "",
  "dependencies": {
    "body-parser": "^1.19.0",
    "compression": "^1.7.4",
    "concurrently": "^5.3.0",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "helmet": "^4.2.0",
    "nodemon": "^2.0.6",
    "path": "^0.12.7"
  }
}

前端 App.js

import React,{ useEffect, useState } from 'react';
import { Route, Switch } from "react-router-dom"

import './App.css';
import Header from "./components/header/header.component"
import ProductItem from './components/product-item/product-item.component';
import Homepage from './pages/homepage.component';
import ProductForm from "./components/product-form/product-form.component";

function App() {

  const [backendData, setBackendData] = useState("No Fetching")

  useEffect(() => {
    callBackedApi()
      .then(res => setBackendData(res.express))
      .catch(err => console.log(err))
  }, [])

  async function callBackedApi(){
    
    const response = await fetch("/express", {
      headers: {
        'Content-Type': 'application/json',
      },
    })
  
    const body = await response.json();

    if(response.status !== 200){
      throw Error(body.message)
    }
    return body;
  }

  return (
    <div className="App">
      {backendData}
      <Header />
      <div>
        <Switch>
          <Route exact path="/" component={Homepage} /> 
          <Route path="/product" component={ProductItem} />
          <Route path="/product-form" component={ProductForm} />
        </Switch>
      </div>
    </div>
  );
}

export default App;

前端 package.json

{
  "name": "armourline",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:5000",
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "bootstrap": "^4.5.2",
    "react": "^16.13.1",
    "react-bootstrap": "^1.3.0",
    "react-dom": "^16.13.1",
    "react-icons": "^3.11.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.3",
    "react-slick": "^0.27.13"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "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"
    ]
  }
}

  

您遇到了路由排序问题。

在生产中,您有以下代码处于活动状态:

// serve the react app files in production
if(process.env.NODE_ENV === "production") {
    app.use(express.static(path.join(__dirname, "client/build")));

    app.get("*", (req, res) => {
        res.sendFile(path.join(__dirname, "client/build", "index.html"))
    })
}

其中将app.get("*", ...)路由放在app.get("/express", ...)路由之前,因此 * 路由将获取请求并将其发送给 HTML,该 HTML 不会解析为JSON。 当路线可能发生冲突时,路线的顺序很重要。

app.get("*", ...) app.get("/express", ...)路线之前移动您的app.get("/express", ...)路线,事实上,* 路线可能应该放在最后,以便所有单独指定的路线都有机会在 * 路由之前获取请求。 就我个人而言,我自己不使用 * 路由,因为它们可能会导致一些问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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