实战
crypto 是 Node.js 的一个核心模块,我们用它生成散列值来加密密码。
crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。
MD5
MD5是一种常用的哈希算法,用于给任意数据一个“签名”。这个签名通常用一个十六进制的字符串表示:
//生成密码的 md5 值
var md5 = crypto.createHash('md5')
//hex 16进制
var password = md5.update('11111').digest('hex');
users.js
//加密模块
var crypto = require('crypto');
注册接口
//注册接口
router.post('/reg', function (req, res) {
var md5 = crypto.createHash('md5');
console.log(req.body);
var pw = md5.update(req.body.password).digest('hex');
}
登录接口
// 登录接口
router.post('/login', function (req, res) {
var md5 = crypto.createHash('md5');
var pw = md5.update(req.body.password).digest('hex');
var userObj = {
username: req.body.username,
password: pw
};
}
发布文章
发布文章接口
users.js
//发布文章
router.post('/publish', (req, res) => {
MongoClient.connect(url, function(err, db) {
var database = db.db(dbname);
database.collection('articles', (err, coll) => {
coll.insertOne(req.body, (err) => {
//res.send('1')
res.redirect('/');
db.close()
})
})
})
})
index.esj 增加如下代码,发布文章使用
<% if(name){ %>
<form action="/users/publish" method="post">
<div>
标题: <input type="text" name="" id="">
</div>
<textarea name="" id="" cols="30" rows="10"></textarea>
<input type="submit" value="发布">
</form>
<%}%>
文章列表
index。js
查到文章数据,在首页中显示
router.get('/', function(req, res, next) {
MongoClient.connect(url, function(err, db) {
if(err) throw err;
var database = db.db(dbname);
database.collection('articles',(err,coll)=>{
coll.find({}).toArray((err,data)=>{
console.log(data);
res.render('index', { name:req.session.name ,data:data});
})
})
})
});
index.ejs 增加如下代码 显示 文章信息
<h2>文章列表</h2>
<ul>
<% for(var i=0; i<data.length; i++) {%>
<li>
<a href="/users/<%= data[i]._id %>">
<h2><%= data[i].title %><h2></h2>
</a>
<p><%= data[i].content %></p>
</li>
<% } %>
</ul>
详情
点击标题进入详情页面 /users/:id
路由配置
users.js
var ObjectID = require('mongodb').ObjectID;
//把id转为ObjectID对象,查询的时候用
//根据id 查询文章
router.get('/articles/:id', (req, res) => {
MongoClient.connect(url, function(err, db) {
var database = db.db(dbname);
database.collection('articles', (err, coll) => {
coll.findOne({'_id':new ObjectID(req.params.id)},function(error,data){
res.render('article',{article:data,name:req.session.name})
})
})
})
});
article.ejs
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
</head>
<body>
<%- include('head.ejs') %>
<% if(name){ %>
<h2>欢迎:
<%- name %>,<a class="btn btn-info" href="/relogin">注销</a>
</h2>
<%}else{%>
<h2>游客
你好</h2>
<% }%>
<button class="btn btn-success" οnclick="location.href='/login'">登陆</button>
<button class="btn btn-info" οnclick="location.href='/register'">注册</button>
<h2><%= article.title %></h2>
<p><%= article.content %></p>
</body>
</html>
列表分页
// index 页面 列表分页
router.get('/index', function(req, res, next) {
var pageNum = 1;//获取到页码
var pageSize = 2;//每页几条数据
console.log(req.query.num)
//默认显示第一页数据,如果传入的有参数 ?num=2 就显示对应页的数据
if(req.query.num){
pageNum = parseInt(req.query.num)
}
MongoClient.connect(url, function(err, db) {
if(err) throw err;
var database = db.db(dbname);
database.collection('articles',(err,coll)=>{
coll.find({},{
skip:(pageNum-1)*pageSize,
limit:pageSize
}).sort({'_id':-1}).toArray(function(err,data){
res.render('index',
{ name:req.session.name ,data:data,pageNum:pageNum});
})
})
})
});
文件上传
<h3>文件上传:</h3>
选择一个文件上传: <br />
<form action="/file_upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" size="50" />
<br />
<input type="submit" value="上传文件" />
</form>
app.js
// 挂载users路由配置之前加入
var multer = require('multer');
var fs = require("fs");
app.use(multer({ dest: '/tmp/'}).array('image'));
users.js
router.post('/file_upload', function (req, res) {
console.log(req.files[0]); // 上传的文件信息
var des_file =path.join(__dirname,"../public/" + req.files[0].originalname);
fs.readFile( req.files[0].path, function (err, data) {
fs.writeFile(des_file, data, function (err) {
if( err ){
console.log( err );
}else{
}
});
});
})
或者使用下面这种设置,上传图片
//上传页面
router.get('/profile',function (req,res) {
res.render('profile');
})
// 上传头像图片
var multer = require('multer');//安装模块
// var upload = multer({ dest: 'public/images/headimage' });
var storage = multer.diskStorage({
//路径
destination: function (req, file, cb) {
cb(null, 'public/images/headimage')
},
filename: function (req, file, cb) {
//文件名字
cb(null, file.fieldname + '-' + Date.now()+'.jpg')
}
})
var upload = multer({ storage: storage })
//上传的post 请求
router.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file 是 `avatar` 文件的信息
res.json({code:1,url:req.file.destination+'/'+req.file.filename})
})
profile模板
下面采用的是表单提交
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h2>文件上传</h2>
<form action="/users/profile" method="post" enctype="multipart/form-data">
<input type="file" name="avatar" /><br/>
<input type="submit" value="submit"/><br/>
</form>
</body>
</html>
也可以采用ajax 提交图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Upload files</title>
<script>
function uploadFile() {
var formData = new FormData();
var files = document.getElementById('file').files;
formData.append('avatar', files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/users/profile', true);
xhr.onload = function (e) {
if (this.status == 200) {
}
};
xhr.send(formData);
}
</script>
</head>
<body>
<h1>use bodyParser middleware and upload files</h1>
<form action="" id="form1" enctype="multipart/form-data">
pls choose files <input type="file" name="file" multiple="multiple" id="file" /></br>
<input type="button" id='btn' value="upload file" οnclick="uploadFile()" />
</form>
<output id="result"></output>
</body>
</html>
图文混排 ueditor
https://ueditor.baidu.com/website/index.html
https://ueditor.baidu.com/website/thirdproject.html
https://github.com/netpi/ueditor
npm install ueditor --save
解压,把ueditor文件夹 放在public文件下
使用方式在app.js文件 ,multer路由前面添加下面代码(防止上传的图片被multer先处理)
var ueditor = require("ueditor");
// /ueditor 入口地址配置 https://github.com/netpi/ueditor/blob/master/example/public/ueditor/ueditor.config.js
// 官方例子是这样的 serverUrl: URL + "php/controller.php"
// 我们要把它改成 serverUrl: URL + 'ue'
app.use("/ueditor/ue", ueditor(path.join(__dirname, 'public'), function(req, res, next) {
// ueditor 客户发起上传图片请求
if(req.query.action === 'uploadimage') {
// 这里你可以获得上传图片的信息
var foo = req.ueditor;
console.log(foo.filename); // exp.png
console.log(foo.encoding); // 7bit
console.log(foo.mimetype); // image/png
// 下面填写你要把图片保存到的路径 ( 以 path.join(__dirname, 'public') 作为根路径)
var img_url = '/images/ue';
console.log(img_url)
res.ue_up(img_url); //你只要输入要保存的地址 。保存操作交给ueditor来做
}
// 客户端发起图片列表请求
else if(req.query.action === 'listimage') {
var dir_url = '/images/ue'; // 要展示给客户端的文件夹路径
res.ue_list(dir_url) // 客户端会列出 dir_url 目录下的所有图片
}
// 客户端发起其它请求
else {
res.setHeader('Content-Type', 'application/json');
// 这里填写 ueditor.config.json 这个文件的路径
res.redirect('/ueditor/ueditor.config.json')
}
}));
index。ejs 做出如下改变
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
</head>
<body>
<%- include('head.ejs') %>
<% if(name){ %>
<h2>欢迎:
<%- name %>,<a class="btn btn-info" href="/relogin">注销</a>
</h2>
<%}else{%>
<h2>游客
你好</h2>
<% }%>
<button class="btn btn-success" οnclick="location.href='/login'">登陆</button>
<button class="btn btn-info" οnclick="location.href='/register'">注册</button>
<h2>文章列表</h2>
<ul>
<% for(var i=0; i<data.length; i++) {%>
<li>
<a href="/users/articles/<%= data[i]._id %>">
<h2><%= data[i].title %><h2></h2>
</a>
<p><%- data[i].content %></p>
</li>
<% } %>
</ul>
<div>
<% if(name){ %>
<form action="/users/publish" method="post">
<div>
标题: <input type="text" name="title" id="">
</div>
<!-- <textarea name="content" id="" cols="30" rows="10"></textarea> -->
<script name='content' id="editor" type="text/plain" style="width:624px;height:300px;"></script>
<input type="submit" value="发布">
</form>
<%}%>
<!-- 配置文件 -->
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.all.min.js">
</script>
<script type="text/javascript" charset="utf-8" src="/ueditor/lang/zh-cn/zh-cn.js">
</script>
<!-- 实例化编辑器 -->
<script type="text/javascript">
var ue = UE.getEditor('editor');
</script>
<div> <a href="/index?num=<%= pageNum-1 %>">上一页</a></div>
<div> <a href="/index?num=<%= pageNum+1 %>">下一页</a></div>
</div>
</body>
</html>