繁体   English   中英

MERN 申请 - NODE.JS req.body 空返回

[英]MERN application - NODE.JS req.body empty return

我将 React redux 工具包与 node.js 一起使用。我花了几个小时试图弄清楚为什么 req.body 是空的(具有更新功能)。 express.json() 中间件在 server.js 中有很好的定义。

后端 - servers.js

    const express = require('express');
    const cors = require('cors');
    const dotenv = require('dotenv').config();
    const { errorHandler } = require('./middleware/errorMiddleware');
    const connectDB = require('./config/db');
    const port = process.env.PORT || 5000;
    
    connectDB();
    
    const app = express();
    app.use(cors());
    
    app.use(express.json());
    app.use(express.urlencoded({ extended: false })); 
    
    app.use('/api/books', require('./routes/bookRoutes'));
    
    app.use(errorHandler);
    
    app.listen(port, () => console.log(`Server started on port ${port}`));

后端 - bookRoutes.js

...
router.put('/:id', updateBook);

后端 - bookController.js

const asyncHandler = require('express-async-handler');

const updateBook = asyncHandler(async (req, res) => {
const book = await Book.findById(req.params.id);

  if (!book) {
    res.status(400);
    throw new Error('Book not found');
  }
  console.log('backend bookController req body: ', req.body);
 `//output : backend bookController req body:  {}`

  const updatedBook = await Book.findByIdAndUpdate(req.params.id, req.body, {
    new: true,
  });

  res.status(200).json(updatedBook);
});

前端 - bookSlice.js

const initialState = {
  books: [],
  isLoading: false,
  isSuccess: false,
  isError: false,
  message: '',
};
//Update  book
export const updateBook = createAsyncThunk(
  'books/update',
  async ({ id, bookData }, thunkAPI) => {
    try {
      console.log('slice bookData : ', bookData);
      `//output: slice bookData : undefined`

      return await bookService.updateBook(id, bookData);
    } catch (error) {
      const message =
        (error.response &&
          error.response.data &&
          error.response.data.message) ||
        error.message ||
        error.toString();
      return thunkAPI.rejectWithValue(message);
    }
  }
);

前端 - bookService.js

const API_URL = 'http://localhost:5000/api/books/';
// Update user book
const updateBook = async (bookId, bookData) => {

  console.log('axios service bookData: ', bookData);
  `//output: slice service: undefined`

  const response = await axios.put(API_URL + bookId, bookData);
 
  return response.data;
};

前端 UpdateBook.jsx

const UpdateBook = () => {
  const { id } = useParams();
  const books = useSelector((state) => state.books.books);
  const book = books.find((b) => b._id === id);

  const dispatch = useDispatch();

  const [title, setTitle] = useState(book.title);
  const [description, setDescription] = useState(book.description);
  const [author, setAuthor] = useState(book.author);

  const handleSubmitButton = (id) => {
    const bookUpdated = {
      title: title,
      description: description,
      author: author,
    };

    dispatch(updateBook({ id, bookUpdated }));

  };

  return (
    <div className="form">
      <div className="title">Update</div>
      <div className="subtitle">Let's update a book!</div>
      <div className="input-container ic1">
        <input
          id="title"
          className="input"
          type="text"
          placeholder=" "
          value={title}
          onChange={(e) => {
            setTitle(e.target.value);
          }}
        />
        <div className="cut" />
        <label htmlFor="title" className="placeholder">
          Title
        </label>
      </div>
      <div className="input-container ic2">
        <input
          id="description"
          className="input"
          type="text"
          placeholder=" "
          value={description}
          onChange={(e) => {
            setDescription(e.target.value);
          }}
        />
        <div className="cut" />
        <label htmlFor="description" className="placeholder">
          description
        </label>
      </div>
      <div className="input-container ic2">
        <input
          id="text"
          className="input"
          type="text"
          placeholder=" "
          value={author}
          onChange={(e) => {
            setAuthor(e.target.value);
          }}
        />
        <div className="cut cut-short" />
        <label htmlFor="text" className="placeholder">
          Author
        </label>
      </div>
      <button
        onClick={() => handleSubmitButton(book._id)}
        type="text"
        className="submit"
      >
        Update book!
      </button>
    </div>
  );
};

export default UpdateBook;

请注意,对于 postman,更新 function 有效。 解决我的问题的想法? 谢谢。

编辑:你能看看我的代码吗: CodeSandbox

在浏览器面板 [Browser(:3000)]: k971xu-3000.sse.codesandbox.io/ 的 3000 端口启动。 在终端和控制台上查看:更新请求正文后为空。 请注意,create function 有效...解决我的问题的想法? 谢谢。

我认为,在后端 - bookController.js 中,你已经做了一些事情。 请参阅express-async-handler 而且您还没有导出 controller。因此,在后端 - bookController.js: 中,导出您的 controller。

exports.updateBook = updateBook;

在后端 - bookRoutes.js:

const bookController = require(<"path of your controller file">);

router.put('/:id',asyncHandler(bookController.updateBook));

暂无
暂无

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

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