创建文章集合规则(model文件夹下的article.js)
这里required(这里接收了一个数组) ture表示为必填字段,第二个为错误信息。(这是数据再插入数据库之前数据库对数据的一个判断)
作者实际是用户集合中的用户,这里通过ref将作者和用户关联(这里作者存的是用户_id)
defult是默认值
// 1.引入mongoose模块
const mongoose = require('mongoose');
// 2.创建文章集合规则
const articleSchema = new mongoose.Schema({
title: {
type: String,
maxlength: 20,
minlength: 4,
required: [true, '请填写文章标题']
},
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: [true, '请传递作者']
},
publishDate: {
type: Date,
default: Date.now
},
cover: {
type: String,
default: null
},
content: {
type: String
}
});
// 3.根据规则创建集合
const Article = mongoose.model('Article', articleSchema);
// 4.将集合做为模块成员进行导出
module.exports = {
Article
}
article文件添加链接(article.art文件)
<a href="/admin/article-edit" class="btn btn-primary new">发布新文章</a>
表单提交核心代码(article.edit.art文件)
这里action对应提交到服务器端地址,提交方式为post
enctype="multipart/form-data"制定文件上传类型为二进制文件(因为我们表单还有提交图片等信息的功能)
<!-- enctype="multipart/form-data"制定文章上传类型为二进制文件 -->
<form class="form-container" action="/admin/article-add" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>标题</label>
<input name="title" type="text" class="form-control" placeholder="请输入文章标题">
</div>
<div class="form-group">
<label>作者</label>
<input name="author" type="text" class="form-control" readonly>
</div>
<div class="form-group">
<label>发布时间</label>
<input name="publishDate" type="date" class="form-control">
</div>
<div class="form-group">
<label for="exampleInputFile">文章封面</label>
<input name="cover" type="file">
<div class="thumbnail-waper">
<img class="img-thumbnail" src="">
</div>
</div>
<div class="form-group">
<label>内容</label>
<textarea name="content" class="form-control" id="editor"></textarea>
</div>
<div class="buttons">
<input type="submit" class="btn btn-primary">
</div>
</form>
表单提交服务器处理(article-add.js)
//引入formidable第三方模块
const formidable = require('formidable');
const path = require('path');
module.exports = (req, res) => {
//创建表单解析对象(可以理解为表单处理方法)
const form = formidable.IncomingForm();
//配置表单上传位置
form.uploadDir = path.join(__dirname, '../', '../', 'public', 'uploads');
//保留上传文件后缀名
form.keepExtensions = true;
//解析表单
form.parse(req, (err,fields,files) => {
res.send(files);
})
}
文件及时预览(article-edit.art)
将用户信息主动显示在文章信息提交栏(userInfo是req.app.locals下的属性,客户端可以直接拿到。@为原文输出)
<div class="form-group">
<label>作者</label>
<input value="{{@userInfo._id}}" name="author" type="text" class="form-control" readonly>
</div>
封面提交预览(article-edit.art)
用FIleReader方法可以进行文件读取,其中readAsDataURL用于二进制文件读取(注意是异步函数),不能通过返回值的方式直接获取结果,需要通过事件监听的方式获取返回结果(onload事件在文件读取结束后会自动调用),通过reader.result获取结果(得到图片编码),将此结果放到img src 下正常显示图片
这里this是file而file下有一个属性为files存储所选择文件信息,files【0】表示选中的第一个文件
//选择文件上传控件
var file = document.getElementById('file');
//获取显示img控件
var preview = document.getElementById('preview');
//当用户上传完文件后
file.onchange = function () {
//创建文件读取对象
var reader = new FileReader();
//读取文件
reader.readAsDataURL(this.files[0]);
//监听onload事件
reader.onload = function () {
preview.src = reader.result;
}
}
将数据存储在数据库(article-add.js)
注意:这里表单上传位置为uploads,不要传相同文件到该路径下,否则会造成客户端一直传递(浏览器转圈)但服务器就是不响应。
//引入formidable第三方模块
const formidable = require('formidable');
//引入文章构造规则
const { Article } = require('../../model/article');
const path = require('path');
module.exports = (req, res) => {
//创建表单解析对象(可以理解为表单处理方法)
const form = formidable.IncomingForm();
//配置表单上传位置
form.uploadDir = path.join(__dirname, '../', '../', 'public', 'uploads');
//保留上传文件后缀名
form.keepExtensions = true;
//解析表单
form.parse(req,async(err, fields, files) => {
//拿到文件存储在服务器路径 files.cover.path.split('public')[1]
//根据传入数据给数据库创建数据
// res.send(files.content);
var cover=files.cover.path.split('public')[1];
await Article.create({
title: fields.title,
author: fields.author,
publishDate: fields.publishDate,
// cover: cover,
content: fields.content
});
res.redirect('/admin/article');
})
}
问题1
出这种类型错误检查下目录名称写对与否
问题2
注意客户端提交表单上传位置为uploads,不要传相同文件到该路径下,否则会造成客户端一直传递(浏览器转圈)但服务器就是不响应。