什么是express?
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。Express 不对 node.js 已有的特性进行二次抽象,只是在它之上扩展了Web应用所需的功能。
1.express的使用
- 创建服务
var server=express(); - 监听
server.listen(8080); - 处理请求
server.use(‘地址’,function(req,res){})
这里的req,res并不是原生的req与res,原生的req与res的功能在express中依然保留,但会新添加一些内容。
比如:原生的res.write()中的第一个参数只能是字符串或者buffer二进制对象,但使用express框架下的res.send()就可以接受json。
2.数据解析
有三种处理数据的方式
server.get(目录,function(req,res){}); ------>处理get
server.post(目录,function(req,res){}); ------>处理post
server.use(目录,function(req,res){}); ------>既能处理get又能处理post
- 处理get
server.use('/',function(req,res){
console.log(req.query);
});
- 处理post
const bodyParser=require('body-parser');
server.use(bodyParser.urlencoded({}));
//注意这里的urlencoded提供两个参数:
//extended:true/false; ------->扩展模式
//limit:2*1024*1024 ------->限制post的规模
server.use('/',function(req,res){
console.log(req.body);
});
- 链式操作------>next()
next()表示下一个动作
const express=require('express');
const bodyParser=require('body-parser');
var server=express();
server.listen(8080);
server.use('/',function(req,res,next){
console.log('a');
//next();
})
server.use('/',function(req,res,next){
console.log('b');
})
//如果没有next()语句,结果为a
//如果有next()语句,结果为a b
- 自己写一个中间件body-parser进行post的处理
//在www目录下写一个middle.js
const querystring=require('querystring');
module.exports=function(req,res,next){
var str='';
req.on('data',function(data){
str+=data;
});
req.on('end',function(){
req.body=querystring.parse(str);
//把字符串变为json
next();
})
};
//在www目录下写一个server.js
const express=require('express');
const bodyParser=require('./middle.js');
var server=express();
server.use(bodyParser);
server.use('/',function(req,res){
console.log(req.body);
})
server.listen(8080);
3.cookie与session
http协议有一个天然的不足------>无状态,两次请求之间服务器无法识别是否为同一个人。
cookie:在浏览器保存一些数据,每次请求都会带过来。不安全,有限(4k)。
session:保存数据在服务端。安全,无限。session是基于cookie实现的。cookie中有一个session的ID,服务器利用sessionid找到session文件读取,写入。
隐患:sessionid:session劫持
(1)与cookie有关
1>.发送cookie
res.cookie(名字,值,{path:'/',maxAge:...(单位:ms)});
path代表在什么目录下可以读取cookie
2>读取cookie
使用中间件:cookie-parser
const cookieParser=require('cookie-parser');
server.use(cookieParser('秘钥'));
3>删除cookie
server.use('/',function(req,res){
res.clearCookie('user');
});
(2) 如何实现对cookie的加密?
方式一:签名
req.secret=‘秘钥’;
res.cookie(名字,值,{signed:true});
//举个例子:
req.secret='aabbccddeeff';
res.cookie('user','blue',{signed:true});
console.log(req.signedCookies);------>签名的cookie
console.log(req.cookies); ------>未签名的cookie
方式二:cookie-encrypter中间件
(3)cookie小练习
const express=require('express');
const cookieParser=require('cookie-parser');
var server=express();
server.use(cookieParser('bbccddeeffss'));
server.use('/',function(req,res){
res.cookie('user','blue',{path:'/aaa',maxAge:30*24*3600*1000,signed:true});
res.send('ok');
console.log(req.url);
console.log(req.signedCookies);
res.end();
});
server.listen(8080);
结果:
(4) session
session存在于服务端由于session不能独立存在,
必须先使用server.use(cookieParser());再使用server.use(cookieSession());
中间件:cookie-session。
当我们使用一个变量使用cookie-session中间件。
因为存在着session劫持,cookie-session强制必须有秘钥。
1>获取session
server.use(cookieSession(){
name:...,
keys:[.,...,...],
maxAge:.....
});
2>处理session
server.use('/',function(req,res){
req.session['count']=.......;
});
3>删除session
delete req.session
(5)session小练习
const express=require('express');
const cookieParser=require('cookie-parser');
const cookieSession=require('cookie-session');
var server=express();
//keys循环取100000个,加大破译难度
var arr=[];
for(var i=0;i<100000;++i){
arr.push('sign_'+Math.random());
}
server.use(cookieParser());
server.use(cookieSession({
keys:arr,
name:'sess',
maxAge:2*3600*1000,
//99*24*3600*1000 ----->maxAge近似取无限的方式
}));
server.use('/',function(req,res){
if(req.session['count']==null){
req.session['count']=1;
}else{
req.session['count']++;
}
console.log(req.session['count']);
res.send('ok');
});
server.listen(8080);
4.模板引擎
- jade:破坏式,侵入式,强依赖
- 特点:a.根据缩进规定层级
b.能够识别单双标签(所有的自定义标签都是双标签)
(1).将jade文件渲染到服务器上
//www目录下的1.jade
html
head
style
body
div
div
div
//根目录下的serverJade.js
const jade=require('jade');
var str=jade.renderFile('./www/1.jade',{pretty:true});
console.log(str);
(2)在jade模板文件中添加属性
属性放在()中,并且英文逗号分隔
//www下的1.jade
html
head
style
script(src="try.js")
body
div
div
div
(3)添加内容
jade是一个聪明的引擎,因为a是行级元素,所以就算有pretty:true美化格式打印出的str也没有空格。
a(href="https://www.baidu.com") 官网
(4)内容与标签嵌套
例如,想要实现:
//html为
<div>
29
<span>33</span>
</div>
//jade应写成
div 29
span 33
(5)特殊的style与class
style属性:
a.当作普通属性
div(style="width:200px;height:200px;color:red;")
b.当作一个jason
div(style={width:'200px',height:'200px',color:'red'})
class属性:
a.当作普通属性
div(class="left-wrap color")
b.当做一个数组
div(class=['left-wrap','color'])
(6)属性的简写
//属性简写
div.box
div#both
//将div中的属性变成json传递
div(title='myfirst',id='one')
div&attributes({title:'myfirst',id:'one'})
(7)‘|’表示原样输出
html
head
body
|aaa
'.'表示里面所有下一级内容原样输出
script.
function main(){
var div=getElementsByTageName('div')[0];
div.innerText='this is a fine day';
};
main();
‘include …(文件名)’
//1.js
function main(){
var div=getElementsByTageName('div')[0];
div.innerText='this is a fine day';
};
main();
//1.jade
script
include 1.js
(8)使用变量
//www下的3.jade
html
head
body
div 我的名字:#{name}
//serverJade.js
const jade=require('jade');
var str=jade.renderFile('./www/3.jade',{pretty:true,name:'blue'});
console.log(str);
(9)jade中写js代码
'-'表示该段为代码
//3.jade
-var a=10;
-var b=9;
div value为#{a+b}
在jade中写循环
//www下的4.jade
-for(var i=0;i<arr.length;++i)
div=arr[i]
//serverJade.js
const jade=require('jade');
var str=jade.renderFile('./www/4.jade',{pretty:true,
arr:['aaa','bbb','ccc','ddd','eee']
})
console.log(str);
在jade中写switch-case
在这里变成了case-when
//4.jade
-var a=3
case a
when 0
div aaa
when 1
div bbb
when 2
div ccc
default
div ddd
(10)js属性中的标签
为避免造成网站安全隐患,(注入式攻击)jade会自动消除js传过来的属性中存在的标签。
'!'表示不消除js传过来的属性中的标签
//4.jade
div!=content
//serverJade.js
const jade=require('jade');
var str=jade.renderFile('./www/4.jade',{pretty:true,
arr:['aaa','bbb','ccc','ddd','eee'],
content:'你好呀<p>今天天气真好</p>花也漂亮<span><span>'
})
console.log(str);
(11)jade小练习
//5.jade
doctype
html
head
meta(charset='utf-8')
title jade测试
style.
div{
width:30px;
height:30px;
background-color:gray;
float:left;
color:white;
line-height:30px;
text-align:center;
margin:1px;
}
.last{
clear:left;
}
body
-var i=0;
-while(i<12)
if i%4==0&&i!=0
div.last=i++
else
div=i++
//serverJade.js
const jade=require('jade');
const fs=require('fs');
var str=jade.renderFile('./www/5.jade',{pretty:true});
fs.writeFile('./build/index.html',str,function(err){
if(err){
console.log('编译失败');
}else{
console.log('成功');
}
})
结果: