【问题标题】:Trying to post data via html-form and JavaScript to RESTapi – gets 404 Cannot Post?尝试通过 html-form 和 JavaScript 将数据发布到 REST api – 得到 404 无法发布?
【发布时间】:2021-04-07 08:36:24
【问题描述】:

我用谷歌搜索了很多,问了很多问题,但找不到答案。 我使用 express 和 mongoose 构建了一个带有 node 和 mongoDB 的简单 RESTapi。该数据库托管在 Atlas 上。使用邮递员访问时,RESTapi 工作正常,没有问题。

要通过站点访问和使用 RESTapi,我可以使用 GET 和 DELETE 方法,但是当尝试使用表单发布数据时,我会收到错误“无法发布/404”。我已经尝试了很多东西,但无法让它发挥作用。 (我不知道它是相关的,但是使某些脚本无法加载的内容安全策略,我试图允许 index.html 的头部元信息中的所有内容,但它不会改变)

请求标头

Accept
    text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding
    gzip, deflate
Accept-Language
    en-US,en;q=0.5
Cache-Control
    no-cache
Connection
    keep-alive
Content-Length
    530
Content-Type
    multipart/form-data; boundary=---------------------------52045656921129358052645853016
Host
    localhost:3000
Origin
    http://localhost:3000
Pragma
    no-cache
Referer
    http://localhost:3000/
Upgrade-Insecure-Requests
    1

RESTapi 和访问的站点在同一个文件夹中,项目结构如下:

代码如下: js/main.js

window.onload = loadCourses();
// Variebles from the form
let formCreate = document.getElementById("formCreate");
let courseIdIn = document.getElementById("courseId");
let courseNameIn = document.getElementById("courseName");
let coursePeriodIn = document.getElementById("coursePeriod");
let message_form = document.getElementById("message_form");

const myForm = document.getElementById('formCreate');

myForm.addEventListener('submit', (e) => {
    console.log('Hello from eventlistner');
    e.preventDefault();
    addCourse();
})

// GET courses
function loadCourses() {
    $.getJSON("http://localhost:3000/courses", function(data) {
        //rensa listan
        console.log(data);
        $("#tbody").html("");
        for(let i = 0; i<data.length; i++) {
            $("tbody").append("<tr><td>" + data[i]._id + "</td>" + "<td>"+ data[i].courseId + "</td>" + "<td>" + data[i].courseName + 
"</td>" + "<td>" + data[i].coursePeriod + "</td>" + "<td><img class='deleteSize' onclick='deleteCourse(\""+data[i]._id+"\")' src='images/delete-photo.svg'alt='ikon radare'></td></tr>");
        }
    });
}

// DELETE course
function deleteCourse(id) {
    console.log(id)
    $.ajax({
        type: "DELETE",
        url: "http://localhost:3000/courses/" + id
    }).done(function(response) {
        console.log(response);
        
        //ladda om listan
        loadCourses();
    });
}

// add course
function addCourse() {
    console.log("Hi from add Course");
    let courseIdEl = courseIdIn .value;
    let courseNameEl = courseNameIn.value;
    let coursePeriodEl = coursePeriodIn.value;

    let courseObj = 
    {
        "courseId": courseIdEl.value,
        "courseName": courseNameEl.value,
        "coursePeriod": coursePeriodEl.value
    }
    console.log(courseObj);
    //Skapar fetch-anrop
    fetch('http://localhost:3000/courses', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': '*/*',
        },
        body: JSON.stringify(courseObj)
    })

    .then(response => response.json())
        .then(data => {
            // message
            let message = data.message;
            message_form.innerHTML = message;
            //document.getElementById("message_form").innerHTML = message;
            loadCourses();
            formCreate.reset();
        })
        .catch(error => {
            console.log('Error: ', error);
        })
}
index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="Content-Security-policy" content="default-src *; 
script-src *;
connect-src *;">
    <link rel="stylesheet" href="css/style.css">
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="js/main.js"></script>
    <script src="main2.js"></script>
    <title>Moment 3 - mongoose.js</title>
</head>

<body>
    <h1>Moment 3 - mongoose.js</h1>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Kurs</th>
                <th>Kursnamn</th>
                <th>Period</th>
                <th>Radera</th>
            </tr>
        </thead>
        <tbody id="tbody">
            <tr>
                <td>1</td>
                <td>DT162G</td>
                <td>JavaScript-basar webbutveckling</td>
                <td>1</td>
                <td><img class="deleteSize" onclick="deleteCourse()" src="images/delete-photo.svg" alt="ikon radare">
                </td>
            </tr>
        </tbody>
    </table>
    <h3>Create course:</h3>
    <form class="forms" action="" id="formCreate" method="POST" enctype="multipart/form-data">
        <!--fält för formulär, hela den grå delen-->
        <fieldset id="field">
            <p class="pfield" id="message_form"></p>
            <label for="courseId">Kurskod:</label><br>
            <input type="text" name="courseId" id="courseId" class="input">
            <br>
            <label for="courseName">Kursnamn:</label><br>
            <input type="text" name="courseName" id="courseName" class="input">
            <br>
            <label for="coursePeriod">Kursperiod:</label><br>
            <input type="number" id="coursePeriod" name="coursePeriod" min="1" max="2">
            <div class="btn-wrapper">
                <button type="submit" name="submitPost" id="btn-create" class="btn btn2">Publish</button>
                <button type="reset" name="deletePost" id="btn-reset" class="btn btn2 btn-reset">Delete
                    field</button>
            </div>
        </fieldset>
    </form>

</body>

</html>

RESTapi 代码

路线/课程.js

const express = require('express');
const router =  express.Router();

// Hämtar schemamodel
const Courses = require('../models/CourseModel');



// Get all courses
router.get('/', async (req, res) => {
    try {
        const allCourses = await Courses.find();
        if(!allCourses) {
            throw Error('No items found');
        } else  {
            res.status(200).json(allCourses);
        }

    } catch(err) {
        res.status(500).json( {msg: err})
    }
})
// GET one course
router.get('/:id', getCourse, (req, res) => {
    res.json(res.course)
})

// Create course
router.post('/', async (req, res) => {
    const newCourse = new Courses({
        courseName: req.body.courseName,
        courseId: req.body.courseId,
        coursePeriod: req.body.coursePeriod
    });

    try {
        const course = await newCourse.save();
        if(!course) {
            throw Error('Something went wrong while saving the post =( ');
        } else {
            // It worked ok, post is created
            res.status(201).json(course);
        }
            
    } catch (err) {
        // bad input from user = 400
        res.status(400).json( {msg: err})
    }
});

// UPDATE one course
router.patch('/:id', getCourse, async (req, res) => {
    // options new = true makes mangoose send back updated data and not old
    let options = { new: true }; 
    try {
        const course = await Courses.findByIdAndUpdate(req.params.id, req.body, options);
        if(!course) {
            throw Error ('Something went wrong while updating the post =( ');
        } else {
             // It worked ok, post is created
             res.json(course).status(201).json( {success: true});
            }
    } catch {
        res.status(400).json( {message: err.message})
    }
})

// DELETE one course
router.delete('/:id', getCourse, async (req, res) => {
   try {
        await res.course.deleteOne();
        res.status(200).json( {message: 'Success: Course is deleted!'})
   } catch (err){
        res.status(503).json( {message: err.message})
   }
})



// Creating middlewhere function to re-use, findbyid. Middlewhere idé = webdev simplified
async function getCourse(req, res, next) {
    let course;
    try {
        course = await Courses.findById(req.params.id)
        if (course == null) {
            return res.status(404).json( {message: 'Cant find any course with that ID'})
        }
    } catch (err) {
        return res.status(500).json( {message: err.message})
    }

    res.course = course;
    next();
}

module.exports = router;

模型/CourseModel.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const CourseSchema = new Schema( {
    courseName: {
        type: String,
        required: true
    },
    courseId: {
        type: String,
        required: true
    }, 
    coursePeriod: {
        type: Number,
        required: true
    }
});

module.exports = mongoose.model('Courses', CourseSchema );
服务器.js

require('dotenv').config();
const express = require('express');
const app = express();
const path = require("path");

const mongoose = require('mongoose');
//const { MONGO_URI } = require('./config');

// Connect to MongoDB
mongoose.connect(process.env.MONGO_URI,{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false  })
    .then(() => console.log('Connected to Mongo Database.'))
    .catch(err => console.log(err));


//BodyParser Middleware, for use of JSON in body 
app.use(express.json());

// skapa statisk sökväg
app.use(express.static(path.join(__dirname, 'public')));


// Routes
const courseRoutes = require('./routes/courses.js')
app.use('/courses', courseRoutes)

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => console.log (`Server run at port ${PORT}`));

【问题讨论】:

    标签: forms post http-status-code-404 http-method


    【解决方案1】:

    嗯,这是 HTML 中的一个愚蠢的错误,javascript 文件 main.js 的脚本源标记位于 head 部分。当然,它必须在 body-tag 之前的底部。我真是太傻了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-19
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      相关资源
      最近更新 更多