我无法在本地部署的 mongodb 服务器中使用 mongoose 正确创建文档。仅创建 id,而不是我发送的完整数据(姓名、电子邮件、密码)。在服务器中,数据看起来像这样
{ "_id": { "$oid": "651d8f91c018db3d9504da2a" }, "__v": 0 }
Mongosh shell 和 MongoDB 指南针工作正常。但是 mongosh shell 给出了这个警告: Access control is not enabled for the database.
。我不知道这是否是一个问题。
架构:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name : {type: String ,
required: true
},
email : {type: String ,
required: true
},
password : {type: String ,
required: true
},
}, {timestamps: true});
module.exports = mongoose.model('user', userSchema);
HTML:
<div class="loginform">
<div class="login">
<label for="name">Name</label><input type="text" id="name" />
</div>
<div class="login">
<label for="email">Email</label><input type="text" id="email" />
</div>
<div class="login">
<label for="password">Password</label
><input type="text" id="password" />
<button id="signinbutton">Create Account</button>
</div>
</div>
在前面发帖请求
async function postData(url = "", data = {}) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
let rdata = await response.json()
return rdata
};
let submit = document.getElementById("signinbutton")
submit.addEventListener("click", async() => {
let name = document.getElementById("name").value
let email = document.getElementById("email").value
let password = document.getElementById("password").value
let resp= await postData("/signin", { name, email, password })
if(resp.success){
alert("user created")
}
})
发帖请求
const express = require('express');
const app = express();
const path = require('path');
const mongoose = require('mongoose');
var bodyParser = require('body-parser')
const postm = require('./models/post');
const User = require('./models/User');
mongoose.connect('mongodb://127.0.0.1/blogbase');
app.use(express.json({extended:true}));
app.use(express.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, "static")));
const port = 3000
app.listen(port, () =>{
console.log('app http://localhost:${port}')
});
app.post('/signin', async(res,req) => {
let user = await User.create(req.body)
console.log(req.body)
res.status(200).json({success: true, user: user })
});
错误
D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:3166
this.$__.validationError = new ValidationError(this);
^
ValidationError: user validation failed: password: Path `password` is required., email: Path `email` is required., name: Path `name` is required.
at Document.invalidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:3166:32)
at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2959:17
at D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1368:9
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
errors: {
password: ValidatorError: Path `password` is required.
at validate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1365:13)
at SchemaType.doValidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1349:7)
at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2951:18
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
properties: {
validator: [Function (anonymous)],
message: 'Path `password` is required.',
type: 'required',
path: 'password',
value: undefined
},
kind: 'required',
path: 'password',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
},
email: ValidatorError: Path `email` is required.
at validate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1365:13)
at SchemaType.doValidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1349:7)
at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2951:18
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
properties: {
validator: [Function (anonymous)],
message: 'Path `email` is required.',
type: 'required',
path: 'email',
value: undefined
},
kind: 'required',
path: 'email',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
},
name: ValidatorError: Path `name` is required.
at validate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1365:13)
at SchemaType.doValidate (D:\webdevedu\LBLOG\node_modules\mongoose\lib\schematype.js:1349:7)
at D:\webdevedu\LBLOG\node_modules\mongoose\lib\document.js:2951:18
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
properties: {
validator: [Function (anonymous)],
message: 'Path `name` is required.',
type: 'required',
path: 'name',
value: undefined
},
kind: 'required',
path: 'name',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'user validation failed'
}
Node.js v18.17.0
[nodemon] app crashed - waiting for file changes before starting...
当您的猫鼬模型尝试创建新用户时,
email
、name
和password
的值未定义。您的代码存在一些问题导致此问题,但看起来值没有被发送。
首先,如果您要提交表单数据,那么实际使用表单更具语义性。我可以看到您正在使用 JS 通过
id
来获取元素,但是 <form>
元素已经提供了一种访问每种类型输入的便捷方法,因此只需为每个输入提供一个 name 属性即可。我会解释。像这样更新你的 HTML:
<form name="loginform" action="/signin">
<div class="login">
<label for="name">Name</label>
<input type="text" id="name" name="name">
</div>
<div class="login">
<label for="email">Email</label>
<input type="text" id="email" name="email">
</div>
<div class="login">
<label for="password">Password</label>
<input type="text" id="password" name="password">
<button id="signinbutton">Create Account</button>
</div>
</form>
接下来,将
addEventListener
绑定到实际表单并阻止其自动提交的默认行为。您也没有对获取网络请求进行错误处理,因此您不知道表单是否正确发送。像这样更新:
const form = document.querySelector('form[name="loginform"]')
form.addEventListener('submit', (e)=>{
e.preventDefault(); //< Prevent the form from submitting
let name = form.elements.name; //< Get each input element
let email = form.elements.email;
let password = form.elements.password;
fetch(form.action, { //< Now run fetch using form.action as url
method: 'POST',
body: JSON.stringify({ name, email, password }),
headers: {
'Content-type': 'application/json; charset=UTF-8',
}
})
.then((response)=>{
return response.json();
})
.then((data)=>{
console.log(data);
//Now handle a successful user creation
})
.catch(error => {
console.error('Error:', error)
//Now handle an unsuccessful user creation
});
});
您在服务器上的发布路由看起来不错,但您再次需要能够捕获任何错误。我建议像这样使用
try/catch
并在错误时向客户端发送适当的响应:
app.post('/signin', async(res,req) => {
console.log(req.body); //< Make sure the form data has been parsed in req.body
try{
const {name, email, password} = req.body; //< Destructure only the values you need
let user = await User.create({name, email, password});
res.status(200).json({success: true, user: user });
}catch(err){
console.log(err);
res.status(400).json({success: false, err: 'Appropriate error message' });
}
});
希望这对您有帮助,祝您的项目好运。