-
个人入门学习用笔记、不过多作为参考依据。如有错误欢迎斧正
-
Express框架
- Express在后台的受欢迎程度与jQuery一样、是企业标准.
- http://www.expressjs.com.cn/
- http://www.expressjs.com/
-
路由能力
const express = require('express'); const app = express(); //get请求的响应 app.get('/',(req,res) => { res.send('你好'); }); //post请求的响应 app.post('/haha',(req,res) => { res.send('这是haha'); }); //所有请求 app.all('/',(req,res) => { res.send('你好'); }); //支持正则表达式(内部表示参数区分) app.get(/^\/student\/([\d]{10})$/,(req,res) =>{ res.send('学生信息.学号:'+req.params[0]); }); //:xxxx可以自定义参数通过.req.params.xxxx提取 app.get('/teacher/:gonghao',(req,res) => { var gonghao; gonghao = req.params.gonghao; res.send('老师信息.工号:'+gonghao); }); app.listen(3000,() =>{ console.log('监听成功'); });
-
与模板引擎配合
与原生ejs相比、不需要fs读取文件、转成字符串、再进行替换输出
const express = require('express'); const app = express(); //此处就相当于引用了ejs app.set('view engine','ejs'); app.get('/',(req,res) => { var json = { 'news':['第一个','第二个','第三个'] } //在工程内存在ejs框架的情况下、并不需要引用ejs即可使用模板 //默认读取文件的路径为./views/xxx。可以直接简写成xxx //讲haha.ejs文件与json模板配合后、返回替换成功的文件。 res.render('haha',json); }); app.listen(3000);
-
RESTful路由设计
- 让get、add、post、delete响应同一个url的不同http请求方式。节约url数量
- html通常只发起get、post。app可能会出现add、delete请求。
const express = require('express'); const app = express(); //设置模板引擎 app.set('view engine','ejs'); app.get('/',(req,res)=>{ //直接返回form.ejs解析成html后的文件 res.render('form'); }); //post和get共用一个url //节约了一个url app.post('/',(req,res) =>{ res.send('成功'); }); app.listen(3000);
-
中间件
get、post、use等、叫做中间件
中间件执行的顺序。
自上而下、当第一个路径匹配成功、默认不继续寻找(即使第一个中并没有send())。
但我们可以通过调用第三个参数next()、让app继续向下搜索响应。需要注意的是next当前函数下不能以再使用send();
const express = require('express'); const app = express(); //正常情况下、'/:Id'已经包含了'/100'所以路由搜索到此为止。 app.get('/:Id',(req,res,next) => { console.log('第一个get'); //通过next、让app继续向下搜索 next(); }); app.get('/100',(req,res) => { console.log('第二个get'); res.send() }); app.listen(3000);
use
use也是一个中间件。
use就是get与post
与get/post不同。他可以匹配目标路径之后所有的子文件夹。
此示例下、admin/aa/xxx/x/x/x/x/x/是可以被检索的。
但是admin/bb则不行const express = require('express'); const app = express(); app.use('/admin/aa', function(req, res, next) { // GET 'http://www.example.com/admin/aa/new' console.log(req.originalUrl); // '/admin/aa/new' console.log(req.baseUrl); // '/admin/aa' console.log(req.path); // '/new' next(); }); //当不实现具体路径的时候、express会自动匹配所有地址 app.use((req,res) => { res.send('你好'); }); app.listen(3000);
静态文件伺服
// 静态文件伺服 const express = require('express'); const app = express(); //所有请求全部先检测静态文件 app.use(express.static('./public')); //只有以/wocao开头的采取读取静态文件 app.use('/wocao',express.static('./wocao')); app.get('/hahaha',(req,res) => { res.send('hahaha') }); app.listen(3000);
此时在浏览器中输入127.0.0.1:3000/xxx.html即可
输入127.0.0.1:3000/wocao/xxx.html也可
输入127.0.0.1:3000/hahaha 显示hahaha(static内部有next()机制)
输入其他显示cannot get
在读取静态文件的情况下、如果只输入文件夹名。会默认读取该文件夹下的index.html文件
404
把通配符放于最后处理。这样没有经过路由的所有页面默认由 404.html 来接管。
// 404 app.get('*', function(req, res){ res.render('404.html', { title: 'No Found' }) });
内容渲染
大多数情况下、渲染用res.render()。将会根据views中的模板文件进行渲染。
如果不想使用views文件夹(比如替换成view2文件夹)
app.set('views','views2'); //也可以跨路径指定(比如指定到上级的views) app.set('views','../views');
如果想写一个快速测试页、当然可以使用res.send()。这个函数将根据内容、自动帮我们设置Content-Type头部和200状态码。
send同end一样只能用一次。
一般send用于返回json等数据。如果想使用不同的状态码,可以
res.status(404).send('sorry,web caonnot find that!');
如果想使用不同的Content-Type,可以
res.set('Content-Type','text/html');
Get请求处理
express会自动帮我们把参数转换成json以及数组.通过req.query得到
const express = require('express'); const app = express(); app.get('*',(req,res) =>{ console.log(req.query); res.send(req.query); }); app.listen(3000);
Post请求
文档推荐使用req.body也就是 body-parse来处理
const express = require('express'); const app = express(); var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.set('view engine','ejs'); app.set('views','../views'); app.get('*',(req,res) =>{ res.render('form'); }); app.post('/',(req,res) => { console.log(req.body); res.send(req.body); }); app.listen(3000);
如果涉及文件上传、依旧需要使用formidable
res.sendFile
如果你想直接返回一个文件、比如html。但又不想耽误用render传输模板文件、可以使用这个
app.get('/test',(req,res) => { res.sendFile(__dirname +'/views/index.html'); });
页面绑定参数
ejs本身就是替换模板、所以:
//最后的404中间件 app.use('*',(req,res) => { res.render('err',{'kirito':'kirito111'}); }); <script> var kirito ='<%= kirito%>'; console.log(kirito) </script>
重定向
定向回上一页
res.redirect('/');
定向到其他路由
res.redirect('/xxx');
Cookie
- HTTP是无状态协议。也就是说当你浏览了一个页面、然后转到同一个网站的另一个页面、服务器无法认识到、这是同一台计算机、同一个浏览器。
- Cookie是一个简单的想法:当访问一个页面的时候、服务器在下行HTTP报文中、命令浏览器储存一个字符串;浏览器再访问同一个域的时候、将把这个字符串携带到上行HTTP请求中。
特点:
- 不加密、用户可以看到
- 用户可以删除、或者禁用
- cookie可以被篡改
- cookie可以用于攻击
- cookie的存储量很小。未来或许要被localstorage(IE9兼容)取代
express中的Cookie
res负责设置cookie
res.cookie(K&V)
req负责识别cookie
通过node设置cookie
res.cookie.key const express = require ('express'); const app = express(); //使用cookie必须使用cookie-parser中间件 const cookieParser = require('cookie-parser'); app.use(cookieParser()); app.get('/',(req,res) => { //maxAge在express中以毫秒为单位 res.cookie('xihao','tfboys',{maxAge:900000,httpOnly:true}); res.send('cookie='+req.cookies.xihao); }); app.listen(3000);
下行报文中
- 上行报文中
Session
保持登录状态
Session从头至尾依赖cookie、一旦禁用/清除cookie、sessiion也会失效
Session作为乱码令牌发还给用户。服务器为令牌存储具体信息
理论上可以存储无线大小的数据
const express = require ('express'); const app = express(); var session = require('express-session'); app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true })); app.get('/login',(req,res) => { //设置session req.session.login = '1'; req.session.username = 'kirito'; res.send('成功登录'); }); app.get('/',(req,res) => { if (req.session.login == '1'){ res.send('欢迎'+req.session.username+'您已成功登录'); }else { res.send('尚未登录'); } }); app.listen(3000);
需要注意的是
若将服务器重新启动、访问根目录。会显示未登录状态
因为login以及username都缓存在服务器的express-session模块内