异步io模块、中间件、路由
url模块
- 如果传入第二个参数为true,则url模块解析后的对象的query属性是一个对象了
- 把浏览器传过来的参数转换成对象
- 代码
var urlObj = url.parse(req.url,true);
urlObj.query--->对象
request通过data事件和end事件来接收post的数据
- 代码
req.on('end',function(){
//处理请求
res.end('成功');//放在里面,是因为通过会先被执行,所以不好进行放在外面
})
同步和异步
- 同步会阻塞后面的代码
- 异步则不会
- 异步中有嵌套才具有先后顺序
异步io模型
异步非i/o操作和异步i/o操作
- 异步非io
- setTimeout和setInterval
- 异步io操作
- 操作文件和网络操作和fs
- 图解1
- 代码执行殊顺序
- 主线程
- 执行
- node运行大概三类 同步和异步(io、分io)
- 执行同步,绕圈
- 顺序执行
- 遇到见io,找子线程
- 自己继续执行,出现异步非io,主线程执行
- 子线程执行完成,主线程多callback
- callback是同步自己执行,异步子线程执行
- 整个代码执行完成
- 执行
- 子线程
- 拿到异步io代码,执行
- 完成后,交给主线程,自己去线程池
- 主线程
- 总结
- node去执行一段代码,里面包含同步、异步io、异步非io
- node出一个主线程,去轮询代码
- 先去执行所有的同步代码,执行完成之后,继续轮询
- 对于异步非io/异步io,先遇见谁就先执行哪个
- 如果先遇到异步非io,就主线程自己去执行
- 在异步非io中,如果符合条件,就将这个异步非io的回调放到队列的尾部
- 继续轮询
- 下面的异步io会去执行吗
- 就是不会阻塞代码的执行
- 异步io开一个子线程,给主线程一个反馈,将回调在队列中
-
主线程进行轮询,看callback….重新从第一个执行…轮询
- 异步非io,主线程会把回调扔回到队列里面来
- 图解2
- 代码
- 从js走,将需要执行的任务放在队列中
- 一行一行执行
- 主线程先将队列中的代码都先执行完
- 继续轮询
- 里面的异步代码
- 如果是异步io,拉一个子线程进行
- 继续轮询
- 遇到异步非io,只是个计时器,满足条件
- 满足条件
- 执行callback到队列中
- 不满足条件
- 继续轮询
- 遇到异步io
- 继续拉子线程
- 子线程完成后,将callback扔回队列的尾部
- 主线程轮询
- 看callback中是不是同异步
- ….
- 出现的问题
- callback里面有什么代码
- 有同步和异步非io和要不非io…
- 注意:
- 是什么
- 回调函数里面
- 是同步还是异步的
- 同步的
- 回调函数里面,也是这一个主线程来控制的吗????
- 只有一个主线程
- 异步要有顺序,是一层嵌套一层
- 是同步还是异步的
- callback里面有什么代码
异步和多线程的比较
- node的异步就是通过异步处理的方式替你去完成多线程的编程
- 比较
- 多线程编程更加灵活
- 异步使用起来更加简单(node帮你去做的)
- node擅长io操作
- 不擅长cpu密集型—>大量的计算,计算是同步,现在
- 规避for循环
express
区别一个什么是框架,什么是类库
- 类库和框架
- 类库
- 类库是你调用他的方法
- 框架
- 框架提供了一套规范,你按照这套规范写,框架再来运行你写的代码
- 类库
express
- 网站
- www.expressjs.com.cn
express-generator脚手架工具
- 命令
- npm install -g express-generator
- 作用
- 帮助我们快速构建网站的
- 脚手架构建项目的目录结构
- app.js
- package.json
- bin是配置文件
- node_modules引入的包
- 其实不用新建的,直接进行npm install
- public
- 放置静态的文件的资源
- routes
- 放置路由的
- views
- 存放模板引擎文件的
- 前端有模板引擎,后端也有模板引擎
为什么使用框架?
app.use(express.static(path.join(__dirname, 'public'))); - 原生Node开发,会发现很多问题。比如: + 呈递静态页面很不方便,需要处理每个HTTP请求 + 路由处理不直观清晰,需要写很多字符串判断和正则表达式 + 不能集中精力写业务,要考虑很多其它的东西 - Express框架致力于解决上述问题。 - 例如,jQuery,简化了dom操作,让我们的关注点从如何去操作dom转变成具体我们要操作dom去干什么。
使用express构建的第一个程序
- 项目开发流程
- 安装脚手架工具
- npm install -g express-generator
- 控制台上打命令
- express 或者 express 加上项目名
- 执行npm install
- 加载package.json中的依赖node_module
- 进行写入口文件app.js
- 安装脚手架工具
- 入口文件代码基本步骤
- 引入express模块
- 引入path模块
- path是一个核心模块,拼接路径的
- var app = express();//也就是类似于创建一个server
- express.static(root, [options])
- 参数
- root 参数指的是静态资源文件所在的根目录
- express.static 是 Express 内置的唯一一个中间件。
- 负责托管 Express 应用内的静态资源。
- 参数
- 下面的代码就是将public目录下的代码托管给express.static
- app.use就是将托管的页面进行挂在在app这个服务上
- 代码
/*
1. 在项目目录下执行express,进行生成目录结构
2. 执行npm install,使用npm下载node_module,就是package.json中的dependencies
3. 写入口文件,就是这个app.js
*/
// 创建一个 Express 应用。
//express() 是一个由 express 模块导出的入口(top-level)函数。
var express = require('express');
var path = require('path');
var app = express();//也就是类似于创建一个server
/*
express.static(root, [options])
- 参数
root 参数指的是静态资源文件所在的根目录
express.static 是 Express 内置的唯一一个中间件。
负责托管 Express 应用内的静态资源。
下面的代码就是将public目录下的代码托管给express.static
app.use就是将托管的页面进行挂在在app这个服务上
*/
app.use(express.static(path.join(__dirname,'public')));
app.listen(3000);
路由
- 概念
- 路由器
- 是告知请求者,所请求的ip在哪里,并且把信息发送过去
- web框架的路由
- 是告知框架,所请求的http参数应该调用的模块、类、方法在哪里,把请求发送过去
- 路由器
- 部分代码
- 上部分代码在express中构建的第一个程序中
- 代码
/*
app.get(path, callback [, callback ...])
HTTP GET请求路由到指定的路径与指定的回调函数
*/
app.get('/getData',function(req,res){
res.send('----GET request to homepage---');
res.end();
});
/*
app.post(path, callback [, callback ...])
HTTP POST请求路由到指定的路径与指定的回调函数
*/
app.post('/getData',function(req,res){
res.send('---POST request to homepage---');
res.end();
})
通过模糊匹配路由
- js模糊匹配
- 当路径当中有一个字符我不记得存不存在了,在这个字符后面使用“?”
- /apples? apples 和 apple
- 当路径中有n个字符我不记得了,用()将这些字符包裹起来再在后面加“?”
- /get(New)? getNew或是get
- 当我们不记得一个字符出现了多少次
- /go+gle o出现一次或是一次以上
- 当请求中,需要将一部分字符模糊匹配的时候用*
- /b*u bu或是b…u
- 使用正则
- /a/ 只有a可以访问
- /.*fly$/看是不是.fly结尾的
- 当路径当中有一个字符我不记得存不存在了,在这个字符后面使用“?”
- 代码
/*
js模糊匹配
1. 当路径当中有一个字符我不记得存不存在了,在这个字符后面使用“?”
/apples? apples 和 apple
2. 当路径中有n个字符我不记得了,用()将这些字符包裹起来再在后面加“?”
/get(New)? getNew或是get
3. 当我们不记得一个字符出现了多少次
/go+gle o出现一次或是一次以上
4. 当请求中,需要将一部分字符模糊匹配的时候用*
/b*u bu或是b...u
5. 使用正则
5.1 /a/ 只有a可以访问
5.2 /.*fly$/看是不是.fly结尾的
*/
app.get('/apples?',function(req,res){
res.end('apple或是apples');
});
app.get('/get(New)?',function(req,res){
res.end('getNew或是get');
});
app.get('/go+gle',function(req,res){
res.end('go....gle,0是一个及其以上');
});
app.get('/b*u',function(req,res){
res.end('bu或是b...u');
});
app.get('/a/',function(req,res){
res.end('接口地址就是a,只有a可以访问');
});
app.get('/.fly$/',function(req,res){
res.end('以.fly结尾的');
})
中间件
什么是中间件?
- 通过 app.use(中间件的代码)使用中间件
- Express 是一个自身功能极简,
- 完全是由路由和中间件构成一个的 web 开发框架
- 从本质上来说,一个 Express 应用就是在调用各种中间件
- 中间件(Middleware)是一个函数,
- 它可以访问请求对象(request object (req)), 响应对象(response object (res)),
- 和 web 应用中处于请求-响应循环流程中的中间件,
- 一般被命名为 next 的变量。
- 往往一个http请求发送到服务器,都需要通过很多的判断和处理。
- 一个请求发送过来—->用户是否已经登录—->用户请求的是什么资源(静态资源、动态页面、json数据)
- —->统计一下用户的请求—>(如果请求的内容不存在)返回404
中间件的功能
- 中间件的功能包括
- 执行任何代码
- 修改请求和响应对象
- 终结请求-响应循环
- 调用堆栈中的下一个中间件
- 如果当前中间件没有终结请求-响应循环
- 则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。
中间件种类
- Express 应用可使用如下几种中间件:
- 内置中间件
- 第三方中间件
- 错误处理中间件
- 应用级中间件
- 路由级中间件
使用中间件
- 使用use进行将中间件挂在在app服务上
- app.use(写一个中间件)
- 两个参数
- 第一个参数路径,可选
- 第二个采纳数,回调函数
- 三个参数
- req
- res
- next
- 注意:
- next是一个方法,被调用后,继续走下一个中间件
- 注意:
- 三个参数
- 两个参数
使用中间件的示例代码
- app.use(中间件),将中间件进行挂在到app上
- app.use(中间件的回调函数)
- 回调函数中的参数
- req 请求对象
- res 响应对象
- next 下一个执行的中间件
- 回调函数中的参数
- app.use(中间件的回调函数)
//引入express和path
var express = require('express');
var path = require('path');
var app = express();//创建一个服务
//通过express.static将public成静态目录托管给express
//再将静态目录挂在到app上
app.use(express.static(path.join(__dirname,'public')));
//app.use(中间件),将中间件进行挂在到app上
/**
* app.use(中间件的回调函数)
* 回调函数中的参数
* 1. req 请求对象
* 2. res 响应对象
* 3. next 下一个执行的中间件
*/
app.use(function(req,res,next){
var cookie = false;
if(cookie){
res.send('返回的数据');
res.end('登录成功');
next();
}else{
//这边不登录成,下面的中间件就不会执行了,没写next()
res.end('请重新登录');
}
});
app.use(function(req,res,next){
console.log('这是第二个执行的中间件');
res.end('这是第二个执行的中间件');
});
app.listen(3000);
总结
- 路由
- 通过一种并联的结构,让你的请求找到唯一对应处理
- 中间件
- 通过串联的形式,把一堆过滤器进行串联起来
path.join
- path.join([…paths])
- 通过path模块的join方法去拼接多个字符串,输出一个正确的路径给你
- console.log(path.join(__dirname,’./test.txt’));
- 拼成一个绝对路径
- 其他的方法看这个代码
var fs = require('fs');
var path = require('path');
//取文件名 myfile.html
var bsn = path.basename('C:\\temp\\myfile.html');
console.log(bsn);
//取路径中的文件夹路径部分 C:\\temp
var dirn = path.dirname('C:\\temp\\myfile.html');
console.log(dirn);
//获取文件的后缀名 .html
var extn = path.extname('index.html');
console.log(extn);
/*path.join([...paths])
通过path模块的join方法去拼接多个字符串,输出一个正确的路径给你*/
console.log(path.join(__dirname,'./test.txt'));
fs.readFile(path.join(__dirname,'./test.txt'),'utf8',function(err,data){
if(err){
console.log(err);
return;
}
console.log(data);
})
postman插件
- 安装chrome插件的第二种方法
- 拖到_meta…进行将前面的_去掉
- 就变成插件文件了
- 直接将文件夹拖到chrome插件中就好了
- 谷歌插件破解方式