mongodb 使用POST从前端向后端发送数据时,CORS阻止对XMLHttpRequest的访问

niwlg2el  于 2023-02-03  发布在  Go
关注(0)|答案(2)|浏览(129)

下面是一些背景知识:我正在做一个全栈的to-do list应用程序。前端基于React和Bootstrap。后端使用Express、Node和MongoDB。问题是当我使用GET从MongoDB获取数据时,我可以在前端查看它。但是当我使用POST发送数据时,我得到这个错误:

Access to XMLHttpRequest at 'http://localhost:5035/api/todos' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我在这里添加所需的代码文件。

前端****待办事项.js

// Handles displaying components related to todo task list
import React, { useState, useEffect } from "react";
import TodoForm from "./TodoForm";
import TodoUpdate from "./TodoUpdate";
import axios from "axios";
function TodoTask() {
    //for the list of tasks
    const [todos, setTodos] = useState([]);
    //add task in the list of tasks
    const addTodo = async todo => {
        //check for empty input 
        if (!todo.text || /^\s*$/.test(todo.text)) {
            return
        }
        const newTodos = [todo, ...todos];
        setTodos(newTodos);
        console.log(todos);
        try {
            await axios.post("http://localhost:5035/api/todos", {
             todo
            });
          } catch (error) {
            console.log(error);
          }

    }

    const ViewAllTodos = () => {
        useEffect(() => {
            getAllTodo();
        }, []);
    }

    const getAllTodo = async () => {
        const response = await axios.get("http://localhost:5035/api/todos");
        setTodos(response.data.Todo);
        console.log(response.data.Todo);
    }

    const updateTodo = (todoId, newValue) => {
        if (!newValue.text || /^\s*$/.test(newValue.text)) {
            return
        }

        setTodos(prev => prev.map(item => (item.id === todoId ? newValue : item)))
    }

    const removeTodo = id => {
        const remove = [...todos].filter(todo => todo.id !== id);
        setTodos(remove);

    }

    const completeTodo = id => {
        let updatedTodos = todos.map(todo => {
            if (todo.id === id) {
                todo.isComplete = !todo.isComplete;
            }
            return todo;
        });

        setTodos(updatedTodos);
    }

    const [message, setMessage] = useState('');

    return (
        <div id="container">
            <h1 className="display-1">My To Do List Application</h1>
            <p className="lead">This is a basic to do list application with complete frontend and backend configuration. For details, check ReadMe.md of this project.</p>
            {/* calling the form component to show a text field */}
            <label htmlFor="formGroupExampleInput">Enter your to do here:</label>
            <TodoForm onSubmit={addTodo} />
            {/* checking if the list is empty, otherwise list all the todos with update and delete button */} 
            {todos.length === 0 ?
                <p className="lead">The list is empty!</p> :
                <TodoUpdate todos={todos} completeTodo={setTodos} removeTodo={removeTodo}
                    updateTodo={updateTodo} />
            }
            {/* {todos.length === 0 ? <p>Empty</p> : 
                todos.map((todo, index) => (
                    <tr key={todo._id}>
                      <td>{todo.priority}</td>
                      <td>{todo.todo}</td>
                    </tr>
                  ))
            }        */}
        </div>
    )
}

export default TodoTask;

**后端:**MongooseServer.js

// import dependencies
const express = require('express');
var bodyParser = require('body-parser');
const mongoose = require('mongoose');
const router = require('./routers/routes');
const cors = require('cors');
// const dbUrl = require('./config/db.config/url')
// set up dependencies

const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/api/', router);

const corsOptions ={
  origin:'http://localhost:3000', 
  credentials:true,            //access-control-allow-credentials:true
  optionSuccessStatus:200,
  methods: "GET, POST"
}

app.use(cors(corsOptions));
//app.use(cors());
// app.use(cors({
//   origin: 'http://localhost:3000',
// }))
// set up mongoose
mongoose.connect("mongodb://127.0.0.1:27017/mytodolist")
  .then(()=> {
    console.log('Database connected');
  })
  .catch((error)=> {
    console.log('Error connecting to database');
  });
// set up port
const port = 5035;
// set up route
app.get('/', (req, res) => {
  res.status(200).json({
    message: 'Welcome to todo list',
  });
});

app.listen(port, () => {
  console.log(`Our server is running on port ${port}`);
});

型号.js

const mongoose = require("mongoose");

const MyTodoListSchema = new mongoose.Schema({
taskId: {
    type: Number,
    required: true,
    unique: true
}, 
todo: {
type: String,
default: "",
required: true
},
priority: {
    type: String,
    default: "high",
    required: true
    },
});
const MyTodoList = mongoose.model("MyTodoList", MyTodoListSchema);
module.exports = MyTodoList;

控制器.js

// import mongoose from 'mongoose';
const mongoose = require('mongoose')
// import {MyTodoList} from '../models/model';
const MyTodoList = require('../models/model');

exports.createTodo = (req, res) => {
  app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "*");
    next();
});
  const todo = new MyTodoList({
    taskId: req.body.taskId,
    todo: req.body.todo,
    priority: req.body.priority,
  });
  return todo
    .save()
    .then((newTodo) => {
      return res.status(201).json({
        success: true,
        message: 'New todo list created successfully',
        MyTodoList: newTodo,
      });
    })
    .catch((error) => {
      res.status(500).json({
        success: false,
        message: 'Server error. Please try again.',
        error: error.message,
      });
    });
}  

//get all todos
exports.getAllTodo = (req, res) => {
      res.setHeader("Access-Control-Allow-Origin", "*")
      res.setHeader("Access-Control-Allow-Credentials", "true");
      res.setHeader("Access-Control-Max-Age", "1800");
      res.setHeader("Access-Control-Allow-Headers", "content-type");
      res.setHeader( "Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, PATCH, OPTIONS" ); 
  MyTodoList.find()
    .select('taskId todo priority')
    // .then( () => {
    //   res.setHeader("Access-Control-Allow-Origin", "*")
    //   res.setHeader("Access-Control-Allow-Credentials", "true");
    //   res.setHeader("Access-Control-Max-Age", "1800");
    //   res.setHeader("Access-Control-Allow-Headers", "content-type");
    //   res.setHeader( "Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, PATCH, OPTIONS" ); 
    // })
    .then((allTodo) => {
      // const response = res.status(200).json( {
      //   success: true,
      //   message: 'A list of all todos',
      //   Todo: allTodo
      // });
      return res.status(200).json({
        // success: true,
        // message: 'A list of all todos',
        Todo: allTodo
      });
      // return response;
    })
    .catch((err) => {
      res.status(500).json({
        success: false,
        message: 'Server error. Please try again.',
        error: err.message,
      });
    });
  }

// module.exports = {createTodo, getAllTodo}

路由.js

const express = require("express");
const cors = require("cors");
const todolist_controller = require('../controllers/controller')
const app = express();
const router = express.Router();
router.post('/todos', todolist_controller.createTodo);
router.get('/todos', todolist_controller.getAllTodo);
module.exports = router;

请告诉我我做错了什么。
Postman的POST运行良好。我使用MVC模式的应用程序。此外,前端和后端是一个主目录中的两个独立目录。两者都运行在不同的端口。前端运行在端口3000,后端运行在端口5035
蒂娅!我被困在这里好几天了。请帮帮忙!

7cwmlq89

7cwmlq891#

如果你想加入所有API端点的白名单,那么在你的路由之前必须调用cors中间件(这也是推荐的),如下所示

const app = express();
const corsOptions ={
  origin:'http://localhost:3000', 
  credentials:true,            //access-control-allow-credentials:true
  optionSuccessStatus:200,
  methods: "GET, POST"
}

app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use('/api/', router); // cors middleware must call before this line
ftf50wuq

ftf50wuq2#

只需在API项目的根使用cors中间件,例如:

const cors = require('cors');
app.use(cors());

相关问题