我正在上一个Web编程课程,我们正在编写Web服务器API。我目前已经实现了POST和GET,但是在实现DELETE时遇到了一些麻烦。我在这里做错了什么?对于我正在做的事情的透彻解释,我将不胜感激,因为我实际上是在尝试学习该材料(除非它当然只是格式化错误)。
还有很多尚未实现的部分,所以我确定有很多错误。通常,我关心的是DELETE,以及我的代码中我不理解的任何其他东西。
我已将域名替换为fakeDomainName.com
index.html和script.js在公共文件夹中。我的主目录中的start.js。
我们正在使用Node.js服务器和MongoDB数据库存储信息来创建一个简单的投票类型api进行练习。当前,POST和GET可以按预期工作,但是DELETE给了我这些错误:
spread.js:25 DELETE http://fakeDomainName.com:3010/api/candidates/undefined 500 (Internal Server Error)
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
Promise.then (async)
r.request @ spread.js:25
r.<computed> @ spread.js:25
(anonymous) @ axios.min.js:477
deleteItem @ script.js:65
invokeWithErrorHandling @ vue.js:1855
invoker @ vue.js:2173
original._wrapper @ vue.js:7416
spread.js:25 Uncaught (in promise) Error: Request failed with status code 500
at e.exports (spread.js:25)
at e.exports (spread.js:25)
at XMLHttpRequest.d.onreadystatechange (spread.js:25)
e.exports @ spread.js:25
e.exports @ spread.js:25
d.onreadystatechange @ spread.js:25
XMLHttpRequest.send (async)
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
Promise.then (async)
r.request @ spread.js:25
r.<computed> @ spread.js:25
(anonymous) @ axios.min.js:477
deleteItem @ script.js:65
invokeWithErrorHandling @ vue.js:1855
invoker @ vue.js:2173
original._wrapper @ vue.js:7416
这是我在“ start.js”中的代码,这是我用来启动服务器的代码。
const express = require('express');
const bodyParser = require("body-parser");
const multer = require('multer');
const upload = multer({
dest: './public/images/',
limits: {
fileSize: 10000000
}
});
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(express.static('public'));
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/voting', {
useNewUrlParser: true
});
var candidateSchema = new mongoose.Schema({
name: String,
bio: String,
numVotes: String,
});
var Candidate = mongoose.model('Candidate', candidateSchema);
//add a candidate to the list
app.post('/api/candidates', async(req, res) => {
console.log("initiated post request");
const candidate = new Candidate({
name: req.body.name,
bio: req.body.bio,
numVotes: req.body.numVotes,
});
this.addItem = candidate.data;
try {
await candidate.save();
}
catch (error) {
console.log(error);
res.sendStatus(500);
}
});
// Get a list of all of the candidates.
app.get('/api/candidates', async(req, res) => {
console.log("initiated get request");
try {
let candidate = await Candidate.find();
res.send(candidate);
}
catch (error) {
console.log(error);
res.sendStatus(500);
}
});
//delete a candidate from the list
app.delete('/api/candidates/:id', async(req, res) => {
console.log("initiated delete request");
Candidate.deleteOne({ _id: req.params.id }, function(err) {
if (err) res.sendStatus(500);
else {
console.log(req.params.id, "deleted successfully");
res.sendStatus(200);
}
});
});
//edit a candidate
app.put('/api/candidates/:id', async(req, res) => {
console.log("initiated put(edit) request");
try {
let candidate = await Candidate.findOne({ _id: req.params.id });
candidate.name = req.body.name;
candidate.bio = req.body.bio;
candidate.numVotes = req.body.numVotes;
candidate.save();
res.sendStatus(200);
}
catch (error) {
console.log(error);
res.sendStatus(500);
}
});
app.listen(3010, () => console.log('Server listening on port 3010!'));
这是我在script.js中的代码,该代码链接到我的index.html页面:
var app = new Vue({
el: '#app',
data: {
name: "",
bio: "",
numVotes: "",
file: null,
addItem: null,
items: [],
findName: "",
findItem: null,
},
created() {
this.getItems();
},
computed: {
suggestions() {
return this.items.filter(item => item.title.toLowerCase().startsWith(this.findTitle.toLowerCase()));
}
},
methods: {
async postItem(item) {
console.log("initiated");
try {
let response = await axios.post('/api/candidates', {
name: this.name,
bio: this.bio,
numVotes: this.numVotes,
});
this.addItem = response.data;
}
catch (error) {
console.log(error);
}
},
async getItems() {
try {
let response = await axios.get("/api/candidates");
this.items = response.data;
return true;
}
catch (error) {
console.log(error);
}
},
selectItem(item) {
this.findName = "";
this.findItem = item;
},
async deleteItem(item) {
try {
let response = axios.delete("/api/candidates/" + item._id);
this.findItem = null;
this.getItems();
return true;
} catch (error) {
console.log(error);
}
},
async editItem(item) {
try {
let response = await axios.put("/api/candidates/" + item._id, {
name: this.findItem.name,
bio: this.findItem.bio,
numVotes: this.findItem.numVotes,
});
this.findItem = null;
this.getItems();
return true;
} catch (error) {
console.log(error);
}
},
},
});
最后,这是我在index.html中使用的代码:
<!DOCTYPE HTML>
<html>
<head>
<title></title>
</head>
<body>
<h2>Hello World</h2>
<div id="app">
<div>
<div>
<input v-model="name" placeholder="Name">
<p></p>
<input v-model="bio" placeholder="Bio">
<p></p>
<input v-model="numVotes" placeholder="Number of votes">
<button @click="postItem">Upload</button>
<button @click="deleteItem">Delete</button>
</div>
<div v-if="addItem">
<h2>{{addItem.name}}</h2>
<h2>{{addItem.bio}}</h2>
<h2>{{addItem.NumVotes}}</h2>
</div>
</div>
<h2>Candidates:</h2>
<div v-for="item in items">
<div @click="selectItem">
<h2>Name: {{item.name}}</h2>
<h2>Bio: {{item.bio}}</h2>
<h2>Number of Votes: {{item.numVotes}}</h2>
</div>
</div>
</div>
<!--Vue and axios-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="/script.js"></script>
</body>
</html>
答案 0 :(得分:0)
正如您在url中看到的那样,您没有获得参数id,其显示为未定义
//fakeDomainName.com:3010/api/candidates/undefined
由于它给了错误,如果您将id传递给它,它将同样有效
//delete a candidate from the list
app.delete('/api/candidates/:id', async(req, res) => {
console.log("initiated delete request");
Candidate.findOneAndDelete({ _id: req.params.id }, function(err) {
if (err) res.sendStatus(500);
else {
console.log(req.params.id, "deleted successfully");
res.sendStatus(200);
}
});
});```
答案 1 :(得分:0)
我用邮递员测试了您的节点。 “删除”很好。但是正如您在错误本身中看到的那样
DELETE http://fakeDomainName.com:3010/api/candidates/undefined
参数item id
的发送未定义,因此无法删除。
在您的POST
请求中(在服务器/节点侧),您可以添加一个sendStatus(200)
以避免挂起发布请求。此外,您可以获取已保存的id
保存Candidate
像这样:
app.post('/api/candidates', async(req, res) => {
console.log("initiated post request");
const candidate = new Candidate({
name: req.body.name,
bio: req.body.bio,
numVotes: req.body.numVotes,
});
this.addItem = candidate.data;
try {
console.log("Await save...");
let data = await candidate.save();
console.log("Done");
res.statusCode = 200;
res.setHeader('content-type','application/json');
res.end(JSON.stringify(data));
}
catch (error) {
console.log(error);
res.sendStatus(500);
}
});
响应如下:
{
"_id": "5dd38cb16f47912b40a1deef",
"name": "Ken Adams",
"bio": "bio",
"numVotes": "10",
"__v": 0
}