1.技术框架介绍
- NodeJS 版本v6.9.5 基础核心开发语言
- Express 一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
- Mongodb 版本v4.9.6
- 第三方模块 & 中间插件
bodyParser:解析post请求数据
cookies:读/写cookie
swig:模板解析引擎
mono goose:操作mongodb数据
markdown:markdown语法解析生成模块
2.安装模块
npm install
npm init 初始化完成后生成package.json文件
npm install --save express 安装完成后package.json中dependencies中多对应的版本号
将所用到的模块都安装好。注:安装过程要联网
3.项目目录结构
4.app.js
5.模板引擎的配置和使用
在后端中写前端的内容对于后期的维护不好,如
res.send('<h1>Welcom to my Blog</h2>');
所以,将界面和逻辑分开
注册这一步其实就是将定义好的模板引擎配置到app中
- 5.1.加载模板
- 5.2.配置应用模板
还可以传递第二个参数,传递给模板使用的数据
在views里面新建index.html
原理:app应用在读取模板的时候第一次读取模板文件(index.html)以后并且把它解析后保存在内存中,下一次再次访问的时候,同样的路径解析同样的模板就不会在文件当中读取解析的,而是从已经存在于内存当中的数据中直接读取然后返回。所以重启应用。但是在实际工作中,常常会不断的修改模板,那么就需要不断的重启服务,很麻烦。
在开发过程中,需要取消模板缓存
//在开发过程中需要取消模板缓存
swig.setDefaults({cache: false});
这样,每次就不需要重新去运行app.js,而是保存模板文件即可。
6.静态文件托管
写模板文件的时候经常会引入外部文件,如图片,css等。
那么头部需要去解析css文件。同时,在后端(app.js)中要写css
但是如果有多个css的话就会写很多get请求,很麻烦。
我们要请求的css和js是静态文件,不需要用这种动态的方法,只需要在后端获取,然后向前端发送。
当用户访问的url以/public开始,那么直接返回对应__dirname+'/public'下的文件
梳理一下这个过程: 用户发送http请求->url->解析路由->找到匹配的规则->执行指定的绑定函数,返回对应内容至用户
在public中新建main.css文件
// app.js
/**
* Created by xiaofeng on 2017/5/1 0001.
*/
/*
* 应用程序的启动(入口)文件
* */
// 加载express模板
var express=require('express');
//创建app应用 => NodeJS Http.createServer();
var app=express();
// 加载模板引擎
var swig=require('swig');
// 设置静态文件托管
// 当用户访问的url以/public开始,那么直接返回对应_dirname+'/public'下的文件
app.use('/public',express.static(__dirname+'/public'));
/*
* 处理请求输出
* */
/*
* 首页
* req request对象
* res response对象
* next函数
* */
// app.get('/',function (req,res,next) {
// // res.send('<h1>欢迎来到我的Blog,这是通过NodeJS搭建的</h1>');
// });
/*
* 配置应用模板
* 定义当前应用所使用的模板引擎
* 第一个参数:模板名称,也是文件后缀名,第二个参数用于解析处理模板的内容的方法
* */
app.engine('html',swig.renderFile);
// 设置模板文件存放的目录,第一个参数必须是views,第二个参数是目录
app.set('views','./views');
// 注册所使用的模板引擎,第一个参数必须的view engine,第二个参数必须和app.engine这个方法中定义的模板名称一致
app.set('view engine','html');
swig.setDefaults({cache:false});
app.get('/',function (req,res,next) {
res.render('index');
});
// 比较麻烦
// app.get('/main.css',function (req,res,next) {
// res.setHeader('content-type','text/css');
// res.send("h1 {text-align:center;}");
// });
// 监听端口 http请求
app.listen(8081);
7.分模块开发与实现
比如: 在router/admin.js
访问 localhost:8081/admin/user
注意:如果现在只是测试,访问admin.js,那么就要将
app.use('/api',require('./routers/api'));
app.use('/',require('./routers/main'));
进行注释,否则会报错。
如果不写这一句,也会报错
module.exports=router;
模块划分
在schema文件夹中新建users.js文件。
连接数据库之前在app.js中加载数据库
var mongoose=require('mongoose');
然后使用mongoose中的connect方法连接数据库。当然,在连接数据库之前要开启数据库。开启数据库先进行数据库的安装。
8.数据库连接、表结构Schema定义、Model创建
mongoose模块进行数据库操作
在官网下载mongodb并且安装;
安装好后找到MongoDB->Server->3.4->bin,有客户端,服务端。通过命令行启动服务端。mongod.exe
等待连接
我们可以通过命令行的方式连接。也可以通过可视化界面连接,如Robomongo
点击“connect”。连接成功后,
接下来是app.js连接数据库
在schemas中新建users.js文件,定义用户的表结构通过Schema方法,仅仅定义表结构不够,需要模型类对数据进行增删改查等操作。在models中新建User.js创建模型类
var mongoose=require('mongoose');
var userSchema=require('../schemas/users');
//创建模型类
module.exports = mongoose.model('User',userSchema );
9.用户注册前端页面逻辑
将静态页面拷贝到Blog相应的文件夹中。
编辑index.js的内容
注册面板中的“注册”按钮是通过ajax实现的,
// index.js
$(function () {
var $loginBox=$('#loginBox');
var $registerBox=$('#registerBox');
//切换到注册面板
$loginBox.find('a').on('click',function () {
$registerBox.show();
$loginBox.hide();
});
$registerBox.find('a').on('click',function () {
$loginBox.show();
$registerBox.hide();
});
//注册,通过ajax实现
$registerBox.find('button').on('click',function () {
//通过ajax提交数据
$.ajax({
type: 'post',
url: '/api/user/register',
data: {
username: $registerBox.find('[name="username"]').val(),
password: $registerBox.find('[name="password"]').val(),
repassword: $registerBox.find('[name="repassword"]').val()
},
dataType: 'json',
success: function (result) {
console.log(result);
}
});
});
})
10.body-parser模块的使用和后端用户名注册的基本验证
测试一下,在api.js中作出修改
// app.js
var express=require('express');
var router=express.Router();
/*
* 用户注册
* 这里router(路由)使用的方法要和index中ajax type属性一致,否则会报错
* */
router.post('/user/register',function (req,res,next) {
res.send('register');
console.log('register');
});
module.exports=router;
接下来需要获取前端提交过来的post数据,如何获取?
需要用到一个第三方模块body-parser,用来处理post提交过来的数据
app.js
// app.js
/*
* 应用程序的启动(入口)文件
* */
//加载express模板
var express=require('express');
//加载模板引擎
var swig=require('swig');
//加载数据库
var mongoose=require('mongoose');
//加载body-parser解析post数据
var bodyParser=require('body-parser');
//创建app应用 => NodeJS Http.createServer();
var app=express();
//设置静态文件托管
//当用户访问的url以/public开始,那么直接返回对应_dirname+'/public'下的文件
app.use('/public',express.static(__dirname+'/public'));
/*
* 配置应用模板
* 定义当前应用所使用的模板引擎
* 第一个参数:模板名称,也是文件后缀名,第二个参数用于解析处理模板的内容的方法
* */
app.engine('html',swig.renderFile);
//设置模板文件存放的目录,第一个参数必须是views,第二个参数是目录
app.set('views','./views');
//注册所使用的模板引擎,第一个参数必须的view engine,第二个参数必须和app.engine这个方法中定义的模板名称一致
app.set('view engine','html');
swig.setDefaults({cache:false});
//body-parser设置
app.use(bodyParser.urlencoded({extended:true}));
app.use('/admin',require('./routers/admin'));
app.use('/api',require('./routers/api'));
app.use('/',require('./routers/main'));
//监听端口 http请求
mongoose.connect('mongodb://localhost:27017/blog',function (err) {
if (err){
console.log('数据库连接失败');
}else {
console.log('数据库连接成功');
app.listen(8081);
}
});
api.js
var express=require('express');
var router=express.Router();
/*
* 用户注册
* 这里router(路由)使用的方法要和index中ajax type属性一致,否则会报错
* */
router.post('/user/register',function (req,res,next) {
//res.send('register');
console.log(req.body);
});
module.exports=router;
点击“注册”后,
用户注册: 注册逻辑的简单实现
var express = require('express');
var router = express.Router();
//统一返回格式
var responseData;
router.use(function (req,res,next) {
responseData = {
code: 0,
message: ''
}
next();
});
/*
* 用户注册
* 注册逻辑:对字符进行验证,并且返回给前端
* 1.用户名不能为空
* 2.密码不能为空
* 3.两次输入的密码必须一致
*
* 1.用户已经被注册
* 数据库中进行查询
*
* 这里router(路由)使用的方法要和index中ajax type属性一致,否则会报错
*
* */
router.post('/user/register', function (req, res, next) {
var username = req.body.username;
var password = req.body.password;
var repassword = req.body.repassword;
//用户名是否为空
if (username == '') {
responseData.code = 1;
responseData.message = "用户名不能为空";
res.json(responseData);
return;
}
//密码不能为空
if (password == '') {
responseData.code = 2;
responseData.message = "密码不能为空";
res.json(responseData);
return;
}
if (password != repassword) {
responseData.code = 3;
responseData.message = "两次输入密码不一致";
res.json(responseData);
return;
}
responseData.message="注册成功";
res.json(responseData);
});
module.exports = router;
重启app.js进行测试