首页 > 解决方案 > MERN 404 发布请求失败

问题描述

我正在尝试发送一个发布请求,但是当我这样做时,我也收到Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0tours-api.js:9 POST http://localhost:3000/ 400 (Bad Request).

我知道当您向服务器发出请求并将响应解析为 JSON 时会发生这种情况,但它不是 JSON,而是响应可能是 HTML。我已经包含了 package.json 文件,因为我的印象是代理需要在那里将 AJAX 调用发送到在 localhost:3001 上运行的 Express 服务器。

我尝试过的: - 将获取请求 url 更改为 '/api/tours' - 删除 package.json 中的 3001 代理 - 在我的 POST 请求中添加额外的 'Accept': 'application/json' 标头 - 更改获取响应以发送文本而不是 JSON,这样做时我收到:

Response {type: "basic", url: "http://localhost:3000/", redirected: false, status: 400, ok: false, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 400
statusText: "Bad Request"
type: "basic"
url: "http://localhost:3000/"
__proto__: Response

我不完全确定为什么响应 url 在文本响应中显示 localhost:3000 以及为什么浏览器中的错误消息也显示了这一点,但我感觉我没有将请求发送到我的后端。对此的任何帮助将不胜感激!

服务器.js

const express = require('express');
const path = require('path');
const logger = require('morgan');
const favicon = require('serve-favicon');
require('./config/database');
require('dotenv').config();


const toursRouter = require('./routes/api/tours');

const app = express();


app.use(favicon(path.join(__dirname, 'build', 'favicon.ico')));
app.use(logger('dev'));
app.use(express.json());
app.use(express.static(path.join(__dirname, 'build')));

// api routes must be before the "catch all" route
app.use('/api/tours', toursRouter);


app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

const port = process.env.PORT || 3001;

app.listen(port, function() {
    console.log(`Express app running on port ${port}`)
})

包.json

    {
  "name": "tourganizer",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "mongoose": "^5.13.7",
    "morgan": "^1.10.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.3",
    "serve-favicon": "^2.5.0",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"



  ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "development": [
    "last 1 chrome version",
    "last 1 firefox version",
    "last 1 safari version"
  ],
  "proxy": "http://localhost:3001"
}

服务/tours-api.js

const BASE_URL = '/api/tours';

export function getAll() {
  return fetch(BASE_URL)
  .then(res => res.json());
}

export async function create(tour) {
    const res = await fetch('/', {
        method: 'POST',
        headers: {'content-type': 'application/json'},
        body: JSON.stringify(tour)
    });
    return await res.json();
}

路线/api/tours.js

const express = require('express');
const router = express.Router();
const toursCtrl = require('../../controllers/api/tours');

router.post('/', toursCtrl.create);

module.exports = router;

addTour 组件

import React, {useState} from 'react';

export default function AddTour({addTour}) {
    const [formState, setFormState] = useState('')
    
    const handleChange = (e) => {
        setFormState(e.target.value);
        };
    const handleSubmit = (e) => {
        e.preventDefault();
        addTour(formState);
        setFormState("");
        };
    return (
        <>
            <form autoComplete="off" onSubmit={handleSubmit}>
                <div className="form-group">
                    <label>Tour Name</label>
                    <input
                        className="form-control"
                        name="name"
                        value={formState}
                        onChange={handleChange}
                    />
                </div>
                <button
                    type="submit"
                    className="btn"
                >
                Add Tour
                </button>
            </form>
        </>
    )
}

应用程序.js

import "./index.css";
import React, { useState } from "react";
import Nav from "./Components/Nav";
import TourList from "./Components/TourList";
import AddTourPage from "./Pages/AddTourPage";
import About from "./Pages/About";
import * as tourAPI from "../src/services/tours-api";
import {BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
    const [tours, setTours] = useState([])

    const addTour = async newTourData => {
      const newTour = await tourAPI.create(newTourData);
      setTours(newTour);
    }
  return (
    <Router>
      <div className='App'>
        <Nav />
        <Switch>
          <Route path='/' exact render={() => 
            <TourList
              tours={tours}
            />
          }/>
          <Route path='/about' exact render={() =>
            <About />
          }
            />
          <Route path='/add' exact render={() =>
            <AddTourPage
              addTour={addTour}
            />
          }/>
        </Switch>
        </div>
      </Router> 
  );
}

标签: reactjsexpressposthttp-status-code-404mern

解决方案


推荐阅读