nodejs学习日记2
# nextTick
nextTick排在当前队列的底部
setTimeout 排在下一个队列的顶部
process.nextTick(function(){
console.log('a')
process.nextTick(function(){
console.log('b')
})
})
2
3
4
5
6
setImmediate 比io 异步高。比setTimeout 优先级要低
// nextTick>setTimeout>setImmediate>异步io
# 模块
require
if(是否在文件模板缓存区中){
//是
返回extend
}else{
if(是否原生模块){
//是
if(是否在原生模块缓存区中){
//否
1.加载原生模块
2.缓存原生模块
}else{
//是
返回extend
}
}esle{
//否
1.查找文件模块
2.根据扩展名载入文件模块
3.缓存文件模块
4.返回extend
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 文件的查找
开始查找文件
1.查找已缓存路径
2.尝试直接查找该文件
3.尝试添加扩展名后查找该文件
4.尝试根据包查找该文件
5.从包描述文件获取文名 (main入口)
6.查找该目录下的index(js/node)
2
3
4
5
6
7
8
# 包
在nodejs中通过包来对一级具有相互依赖关系的模块进行统一管理。一个包就是一个目录。
- package.json包描述文件
- bin二进制
- lib存放javascript文件
- doc说明文档
- test单元测试和其它测试
# npm包管理
- npm search xxx 查找包
- npm view gulp 查看包
- npm install gulp 安装包
- npm install -g express-generator 全局安装包 npm config ls 列出所有的配置 prefix 全局安装目录 cliconfig 命令行配置文件 userconfig 用户配置文件 builtin 内置配置文件 npm root -g 查看全局路径
- npm config set prefix "d:\global" 修改全局路径
- npmlist 显示当前目录下所有包
- npmlist -g 显示全局下所有包
- npm unistall gulp 卸载本地版本
- npm unistall gulp -g 卸载全局下的包
- npm update gulp 更新本地gulp
- npm update -g gulp 更新全局下的gulp
- npm update 更新当前目录下所有的包
- npm shrinkwrap 使版本不升级 利用shrinkwrap锁定依赖版本
- npm prune 移除掉不在package.json中的模块
利用shrinkwrap锁定依赖版本 (opens new window)
# npm获取配置的6种方式,优先级由高到低
命令行参数, --proxy http://server:port 即将proxy的值设为http://server:port
环境变量,以npm_config_为前缀的环境变量将会被认为是npm的配置属性。如设置proxy可以加入这样的环境变量npm_config
用户配置文件。可以通过npm config get userconfig查看文件路径,如果是mac系统的话默认路径就是$HOME/.npmrc.
全局配置文件。可以npm config get globalconfig查看文件路径,mac系统的默认路径是/usr/local/etc/npmrc
内置配置文件。安装npm的目录的的npmrc文件
默认配置。 npm本身有默认配置参数,如果以上5条都没设置,则npm会使用默认参数。
为npm设置代理
- npm config set proxy htpp://server:port
2
3
4
5
6
7
8
npm add user 输入用户名邮箱注册 发布包
# buffer 对象进行二进制数据处理
- 缓存区Buffer是暂时存放输入输出数据的一段内存
- JS语言自身只有字符串数据类型,没有二进制数据类型,而在处理TCP和文件流的时候,必须要处理二进制数据
- NodeJS提供了一个Buffer对象来提供对二进制数据的操作
- 是一个表示固定内存分配的全局对象,也就是说要放到缓存区中的字节数需要提前确定
# fs模块中几种流的读写方法的区别
异步 同步
- 将文件作为整体读入缓存区 readFile readFileSync
- 将文件部分读入缓存区 read readSync
- 将数据完整写入文件 writeFile writeFileSync
- 将缓存区的部分内容写入文件 write writeSync
2
3
4
5
6
# stram
- 流是一组有序的,有起点和终点的字节数据传输手段
- 不关心文件的整体内容,只关注是否从文件中读到了数据,以及读到数据之后的处理
- 流是一个抽象接口,被Node中的很多对象所实现。比如对一个HTTP服务器的请求对象request是一个流,stdout也是一个流。
- 流是可读、可写或者兼具两者的。所有流都是EventEmitter的实例。“几乎所有Node程序,无论多简单,都在某种途径用到了流”
stream.Readable可读流
fs.ReadStream 读取文件
http.IncomingMessage客户端的请求或服务器端的响应
net.Scoket tcp连接中的socket对象
process.stdin 标准输入流
Gzip 数据压缩
可读流 有两种,内部有flowing(流动)步和非flowing(暂停)模式来读取数据。
flowing 模式使用操作系统珠内部IO机制来读取数据,并尽可能快地提供给您
非flowing 模式时流默认处于暂停步,必须显式调用read方法来读取数据
“注意” 如果没有绑定data事件处理器,并且没有pipe()目标,同时流被切换到流动模式,那么数据会流失。
# 中间件
- 中间件(middleware)就是处理HTTP请求的函数,用业完成各种特定任务,比如检查用户是否登录、分析数据、以及其它在需 要最终将数据发送给用户之前完成的任务
- 它最大的特点就是,一个中间件处理完,可以把相应数据再传递给下一个中间件
var express = require('express');
var app = express();
//中央
app.use(function(req,res,next){
console.log('中央');
req.mny = 100;
next();
});
2
3
4
5
6
7
8
2.特点
- 每个中间件都可以控制流程是否继续执行 next();才会继续执行
- req res 相同对象
- 如果出错了,转交错误处理中间件进行处理
# cookie
- 通过响应头向客户端设置cookie Set-Cookie:name=abc
- 读取客户端过来的cookie Cooke:key1=value1;key2=value2
# referer
可以通过设置ip白名单控制用户访问权限
# etag
当最后修改时间存在问题
1. 某些服务器不能精确得到文件的最后修改时间,这样就无法通过最后修改时间来判断文件是否更新了
2. 某些文件的修改非常频繁,在秒以后的时间内进行修改,Last-Modified只能精确到秒
3. 一些文件的最后修改时间改变了,但是内容并未改弯。我们不希望客户端认为这个文件修改
4. 如果同样的一个文件位于多个CDN服务器上的时候内容虽一样,修改时间不一样
2
3
4
ETag是实体标签的缩写,根据实体内容生成的一段,字符串,可以标识资源的状态。当资源发送改变时,ETag也随之发生变化。ETag是web服务端产生的,然后发给浏览器客户端
- 客户端想判断缓存是否可用可以先获取缓存中文档的ETag,然后通过If-None-Match发送请求给Web服务器询问此缓存是否可用。
- 服务器收到请求,将服务器中的此文件的ETag,跟请求头中的If-None-Match相比较,如果值是一样的,说明缓存还是最新的,web服务器将发送304 Not Modified 响应码给客户端表示缓存未修改过,可以使用
- 如果不一样,则web服务器将发送该文档的最新版本给浏览器客户端
# 浏览器如何不发请求
浏览器会将文件缓存到Cache目录,第二次请求时浏览器会先检查Cache目录下是否含有该文件,如果有,并且还没到Expires设置时间,即文件还没有过期,那么此时浏览器将直接从Cache目录中读取文件,而不再发送请求
- Expires是服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求
- Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据,如果同时设置的话,其优先级高于Expires
# authorization
Authentication:认证,就是验证一个用户是不是它所声明的身份的过程。 Authorization:授权,就是判断是否用户有做某件事的权利。