语言:node.js
框架:express
编辑器: webstorm
数据库:mongodb
首先呢在webstorm中创建项目 { 在命令行下输入npm init 一路回车 最后yes } ( 在webstorm中打开命令行的快捷键是alt+f12 )
再在目录下输入npm install --save express
此时目录为:
还需安装如下的中间件:
body-parser : 解析post请求数据
cookies: 读/写cookie
swig: 模板解析引擎
mongoose: 操作mongodb数据库
markdown: markdown语法解析生成模块
{ 安装的方法为 npm install body-parser }
安装后如下:
接下来我们要创建项目的目录
db: 数据库储存目录
models: 数据库模型文件目录
node_modules: node第三方模块目录
public: 公共文件目录(css js .....)
routers: 路由文件目录
schemas: 数据库结构目录
views: 模板视图文件目录
app.js: 应用(启动)入口文件
在app.js下编写代码:
//加载express模块
var express = require('express');
//创建app应用 => (等同于) NodeJS Http.createServer();
var app = express();
//监听http请求
app.listen(8081);
右键点击 Run'app.js' //在webstorm下这一步真的是方便啊 不像在code下 还需要在目录命令行下执行 npm in start !!! 这一步方便啊啊啊啊啊啊啊啊啊啊啊啊啊啊
在浏览器下输入localhost:8081/
显示:
Cannot GET /
(这个因为没有去处理用户的任何请求)
app.js下编写:
//加载express模块
var express = require('express');
//创建app应用 => (等同于) NodeJS Http.createServer();
var app = express();
/*
* 首页
* req : request对象
* res : response 对象
* next : next函数
**/
app.get('/',function(req,res,next){
res.send('<h1> 欢迎光临我的博客! </h1>')
})
//监听http请求
app.listen(8081);
再重新启动,更新浏览器
欢迎光临我的博客!
但是!但是!如果把前端代码也写到app.js中的话,那么后期维护起来是不是炒鸡麻烦啊 /-v-/
所以,我们要封装起来
在views 下创建index.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel = "stylesheet" type = "text/css" href="/public/main.css"/>
</head>
<body>
<h1>!!!!欢迎光临我的博客!!!!</h1>
</body>
</html>
// <link rel = "stylesheet" type = "text/css" href="/public/main.css"/> 的作用是外联css样式文件(作用同样也是封装起来,以便于后期的维护)
在 public目录下创建main.css文件 (被外联的css样式文件)
突然增加了这么多的外联样式文件 那我们是吧是也需要把app.js文件进行相应的修改呢
如下:
//加载express模块
var express = require('express');
//创建app应用 => (等同于) NodeJS Http.createServer();
var app = express();
//加载模板处理模块
var swig = require('swig');
//配置应用模板
//定义当前应用所使用的模板引擎
//第一个参数:模板引擎的名称,同时也是模板文件的后缀,第二个参数表示用于解析处理模板内容的方法
app.engine('html',swig.renderFile);
//设置模板文件存放的目录,第一个参数必须是views,第二个参数是目录的路径
app.set('views','./views');
//注册使用的模板引擎,第一个参数必须是 view engine,第二个参数和app.engine这个方法中定义的模板引擎的名称(第一个参数)是一致的
app.set('view engine','html');
//在开发过程中,需要关闭模板缓冲功能
swig.setDefaults({cache:false}); //有助于开发过程中的调试
//设置静态文件托管
//当用户访问的url以public开始,那么直接返回对应的__dirname + '/public'下的文件
app.use('/public',express.static(__dirname + '/public'));
/*
* req : request对象
* res : response 对象
* next : next函数
*/
app.get('/',function(req,res,next){
//res.send('<h1> 欢迎光临我的博客! </h1>')
/*
* 读取views目录下的指定文件,解析并且返回给客户端
* 第一个参数:表示模板文件,相当于views目录 view/index.html
* 第二个参数:传递给模板使用的数据(此时没有涉及第二个参数)
* */
res.render('index'); //外联index.html文件
})
//监听http请求
app.listen(8081);
/*
用户发送http请求 => url => 解析路由 => 找到匹配的规则 => 执行指定的绑定函数,返回对应内容给用户
/public => 静态(从public下拿到直接返回)=> 直接读取指定目录下的文件,返回给用户
/其他 => 动态(从后端返回) => 处理业务逻辑,加载模板 => 返回数据给用户
*/
!再划重点 ! 模块划分,方便维护
xiasnhddasdfdasfasd ddasda sd
划分模块
根据功能进行模块划分
前台模块
后台管理模块
API模块
使用app.use()进行模块划分
app.use('/admin',require('./router/admin'));
app.use('api',require('./router/api'));
app.use('/',require('./router./main'));
我们怎么调用模块呢?
在router目录下创建admin.js文件 内容为:
var express = require('express'); var router = express.Router(); router.get('/user',function(req,res,next){ res.send('Admin - User'); }); module.exports = router; //意思是对外暴露了接口router 供其他页面调用
在app.js 中代码 :
app.use('/admin',require('./router/admin'));
此时重启进程
输入: localhost:8081/admin/user
页面展示: Admin - User
-------------------------------------------------------------------------------------------
mongodb 的使用:
首先:我们要在app.js 中添加
// 加载数据库处理模块
var mongoose = require('mongoose');
其次:在app.listen(8081); 处添加
mongoose.connect(); //连接数据库
注:mongodb数据库的连接可视化工具用到了Rob 3T
数据库连接:
mongoose.connect('mongodb://localhost:27018/blog',function(err){
if(err){ console.log('数据路连接失败'); }else{ console.log('数据库连接成功'); app.listen(8081); } }); //连接数据库
==========================================================================
在app.js中有以下代码:
app.use('/', require('./routers/main'));
在routers/main目录下代码为:
var express = require('express'); var router = express.Router(); router.get('/',function(req,res,next){ res.render('main/index'); }); module.exports = router; //意思是对外暴露了接口router 供其他页面调用
在views/main/index目录下为html页面展示的代码
接下来为后端的注册的逻辑的:
在public/js目录下创建index.js以及jquery-1.12.4min.js 将这两个文件外联到index.html上
代码为:
<head> <meta charset="utf-8"> <title>博客</title> <link href="/public/css/main.css" rel="stylesheet" type="text/css"> <link href="/public/fontAwesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> <script src="/public/js/jquery-1.12.4.min.js"></script> <script src="/public/js/index.js"></script> </head>
public/js/index.js下的简单逻辑:
<--index.js存在的意义又是什么呢?-->
在index.js中处理了简单的逻辑,切换界面的逻辑(隐藏,显示的调控)
注册逻辑的思路为:当点击<button>组件时,触发事件。这里用到了ajax(异步的javascript和XML,用于快速创建动态网页的技术,部分数据刷新)
$(function () { var $loginBox = $('#loginBox'); var $registerBox = $('#registerBox'); var $userInfo = $('#userInfo'); //切换到注册面板 $loginBox.find('a.colMint').on('click',function () { $registerBox.show(); $loginBox.hide(); }); //切换到登录面板 $registerBox.find('a.colMint').on('click',function () { $loginBox.show(); $registerBox.hide(); }); //注册 $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); } }) }) })
因为ajax中的
url:'/api/user/register',
所以我们要在routers/api.js目录下代码:
//以下代码若想实现的话,那么必须得再添加中间件!!
router.post('/user/register',function(req,res,next){ console.log( req.body ); //body为req下的一个属性 });
我们不妨YY一下:你在某页面注册账号,那么你的注册信息是不是应该会从前端吧数据发送到后端呢? 是的,准没错!
如果你想操作这个过程的话,那么你就必须得再添加一个中间件(body-parser)
在app.js中添加
//加载body-parser,用来处理post提交过来的数据 var bodyParser = require('body-parser');
//body-parser设置 app.use(bodyParser.urlencoded({extended:true}));
这时我们点击注册<button>就可以console.log出来前端输入得数据
这个时候我们是不是应该做一些验证得操作啊!!!
在api.js中新填如下代码:
var User = require('../models/User'); // 外联../models/User目录
并在头部添加
//用户名是否已经被注册了,如果数据库中已经存在和我们要注册的用户名同名的数据,表示该用户名已经被注册了 User.findOne({ //User.findOne为数据库的查找函数 username: username }).then(function( userInfo ) { if ( userInfo ) { //表示数据库中有该记录 responseData.code = 4; responseData.message = '用户名已经被注册了'; res.json(responseData); return; } //保存用户注册的信息到数据库中 var user = new User({ username: username, password: password }); return user.save(); }).then(function(newUserInfo) { responseData.message = '注册成功'; res.json(responseData); }); });
../models/User目录代码为:
var mongoose = require('mongoose'); var usersSchema = require('../schemas/users'); module.exports = mongoose.model('User', usersSchema);
在index.js下修改代码:
success:function (result) { $registerBox.find('.colWarning').html(result.message); //在首页的注册框下面有一个<p>标签 从而在<p>标签上面显示message内容! if (!result.code){ //注册成功 setTimeout(function () { $loginBox.show(); $registerBox.hide(); },1000); //注册成功的话会控制页面的显隐 } }登录注册的html代码为:
<div class="rightBox" id="loginBox"> <div class="title"><span>登录</span></div> <div class="line"><span class="colDark">用户名:</span><input name="username" type="text" /><em></em></div> <div class="line"><span class="colDark">密码:</span><input name="password" type="password" /><em></em></div> <div class="line"><span class="colDark"></span><button>登 录</button></div> <p class="textRight">还没注册?<a href="javascript:;" class="colMint">马上注册</a> </p> <p class="colWarning textCenter"></p> </div> <div class="rightBox" id="registerBox" style="display: none;"> <div class="title"><span>注册</span></div> <div class="line"><span class="colDark">用户名:</span><input name="username" type="text" /></div> <div class="line"><span class="colDark">密码:</span><input name="password" type="password" /></div> <div class="line"><span class="colDark">确认:</span><input name="repassword" type="password" /></div> <div class="line"><span class="colDark"></span><button>注 册</button></div> <p class="textRight">已有账号?<a href="javascript:;" class="colMint">马上登录</a> </p> <p class="colWarning textCenter"></p> </div>
在这里我们实现了
注册页面从数据库的交互(注册界面下方有<p>标签用来了作为提示行 是否注册成功) 和 与登录界面的显隐控制
接下里就是用户的登录模块
api.js中的登录代码:
/* * 登录 * */ router.post('/user/login', function(req, res) { var username = req.body.username; var password = req.body.password; if ( username == '' || password == '' ) { responseData.code = 1; responseData.message = '用户名和密码不能为空'; res.json(responseData); return; } //查询数据库中相同用户名和密码的记录是否存在,如果存在则登录成功 User.findOne({ username: username, password: password }).then(function(userInfo) { if (!userInfo) { responseData.code = 2; responseData.message = '用户名或密码错误'; res.json(responseData); return; } //用户名和密码是正确的 responseData.message = '登录成功'; responseData.userInfo = { _id: userInfo._id, username: userInfo.username } req.cookies.set('userInfo', JSON.stringify({ _id: userInfo._id, username: userInfo.username })); res.json(responseData); return; }) });
index.js中的代码:
//登录 $loginBox.find('button').on('click', function() { //通过ajax提交请求 异步的javascript和XML,用于快速创建动态网页的技术,部分数据刷新 $.ajax({ type: 'post', url: '/api/user/login', data: { username: $loginBox.find('[name="username"]').val(), password: $loginBox.find('[name="password"]').val() }, dataType: 'json', success: function(result) { $loginBox.find('.colWarning').html(result.message); if (!result.code) { //登录成功 window.location.reload(); } } }) })
登录成功后的html界面:
<div class="rightBox" id="userInfo"> <div class="title"><span>用户信息</span></div> <p><span class="colDark">{{userInfo.username}}</span></p> {% if userInfo.isAdmin %} <p> <span class="colDanger">你好,管理员!</span> <a href="/admin">进入管理</a> </p> {% else %} <p><span class="colDanger">你好,欢迎光临我的博客!</span></p> {% endif %} <p>
</div>