[toc]
0.0.0.0 表示一个无效的,未知的或者不可用的目标 在服务器中,0.0.0.0 指的是本机上的所有 IPV4 地址,如果一个主机有两个 IP 地址,并且该主机上的一个服务监听的地址是 0.0.0.0,那么通过两个 ip 地址都能够访问该服务。 在路由中,0.0.0.0 表示的是默认路由,即当路由表中没有找到完全匹配的路由的时候所对应的路由。
127.0.0.1 属于{127,}集合中的一个,而所有网络号为 127 的地址都被称之为回环地址;大部分 Web 容器测试的时候绑定的本机地址
localhost 是个域名
node 与 Deno 异同
node 为 js 的运行平台;Deno 为 js 和 ts 的运行平台
Deno 采用沙箱模式运行代码,某些权限需要配置添加
后端认证方式:
- 传统的 session 认证
用户认证记录保存在内存中的话,用户下次请求必须要请求在这台服务器上,才能拿到授权的资源,服务端的开销会明显增大,这样在分布式的应用上,相应的限制了负载均衡器的能力
- 基于 token 的鉴权
不需要去考虑用户在哪一台服务器登录 ,客户端存储 token,并在每次请求时附送上这个 token 值 服务端验证 token 值,并返回数据 ;服务端要支持 CORS(跨来源资源共享)策略
- Json web token (JWT)
Header.Payload.Signature
三部分生成 token
// Header 会被 base64 编码
{
'type': 'JWT',
'alg': 'HS256' 算法
}
// 会被base64编码
{
'sub': ''
'name':''
'admin':true
}
// 签名:将各个部分编码后用 . 连接; 用的算法就是Header中的
一种标准 特别适用于分布式站点的单点登录(用户只需要登录一次就可以访问所有相互信任的应用系统)
token 需要查库验证 token 是否有效,而 JWT 不用查库或者少查库
利用 secret 来加密和解密 所以千万不能泄露
npm-shrinkwrap.json 和 package-lock.json 区别
- shrinkwrap 向后兼容 npm 版本 2,3 和 4
- package-lock 只能被 npm 5+识别
- 可以通过运行 npm shrinkwrap package-lock.json 将现有的 package-lock.json 转换为 npm-shrinkwrap.json
- shrinkwrap 应该用于库来保证安装程序包的每个人都获得完全相同的所有依赖项版本
- package-lock 允许安装程序包的人使用与 package.json 指定的版本范围兼容的任何版本的依赖项
- npm install 操作会自动生成 package-lock 文件 并且更新该文件
- 如果是用的 cnpm 安装的包 注意要 npm install 操作一次 更新 package-lock 文件
package.json
devdependencies 表示开发过程中依赖的包; dependencies 表示项目在生产环境中依赖的包
- 尖括号只限大版本号: 比入^0.1.1,如果有小于 1.0.0 的版本都可自动更新,超过就保持 0.9.9
- 波浪号表示只监控最小版本号的更新(如~0.1.2,当有大于该版本号且小于 0.2.0 才更新)
"main":"" // 出口文件 默认根目录下 index.js
"script":{
"test":"grunt test"
}
"engines":{
"node":">=0.10.0"
} //便是node版本需求
npm start 和 npm test 可以直接用;其它用 npm run
npm install 默认两个下的都安装,--production 只安装 dependences 的
如果不是安装在 c 盘需要设置环境变量
设置使用 es6 语法,package.json 设置 "type": "module" 文件用 .mjs, 注意语法不用 es6 的话可能会报错
模块的分类
- 一.核心模块
- 二.文件模块
- 三.第三方模块
基础知识
p
rocess.env 为 node 的全局变量;设置 p
rocess.env.some = 'value'; 在 CommonJS 模块中加载 json 文件,只需通过 require()函数直接加载即可得到 json 对象
node 中的 map()、forEach()、for()循环有一个特性:当其函数里面里面有回调它就变成异步
Node 里面没有全局命名空间的概念
url.parse('http://www.imooc.com/video/6710')
protocol:'http:',表示底层的协议
slashes:true,有没有协议后面的双斜线;
host:ip 地址或是域名;
port:端口
hostname:主机名;
还可以加传两个参数
第二个参数:默认 false,设置为 true,就会用 queryString 来解析 query 的字符串,会将 query 的值解析为对象模式;
第三个参数:默认 false,设置为 true,就会对没有明确协议的 url 进行正确解析;
url.format({});生成一个 url 地址;
HTTP:
浏览器搜索自身 DNS 缓存,如果有就看有没有过期如果过期就结束,就开始搜索操作系统的 DNS 缓存,若也没有就读去本地 Host 文件,若也没有浏览器就会发起一个 DNS 系统调用(一般是运营商的),运营商服务器会产看自身的缓存,一直逐层请求解析 DNS
About:DNS
chrome://net-internals/#dns
node 的全局对象 global 相当于浏览器中的 window
cheerio 是 nodejs 的抓取页面模块,为服务器特别定制的,快速、灵活、实施的 jQuery 核心实现。适合各种 Web 爬虫程序。
官方建议对一个事件不要设置超过十个监听器。太多的话可能会导致内存泄露(内存空间使用后没有收回)。
var eventsEmitter = require("events").EventEmitter;
var life = new eventsEmitter();
life.on("e1", function (w) {
console.log("事件1是:" + w);
});
life.emit("e1", 11);
更改监听数量
life.setMaxListeners(数量);
查看是否被监听过
life.emit()会返回一个布尔 boolean 值;如果监听返回 true;移除某个事件
life.removeListener('事件名',具名函数名 f)
life.on(事件名,函数名 f);
批量移除
life.removeAllListeners(事件名);
某个事件的个数;
life.listeners(事件名).length 或
eventsEmitter.listenerCount(life(实例化),事件名)
path.join() 也可以用 ../
console.log(path.join(__dirname, 'a', 'b')) // C:\folder1\folder2\a\b
path.resolve() 任意一个参数是以/
开头都直接转到根目录 ../
是会在上一个参数的基础上返回上一级目录进行拼接
.resolve(); // G:\GitHub\webpack-pure
.resolve('a/b', 'c'); // G:\GitHub\webpack-pure\a\b\c
.resolve('a/b', 'c', '/k'); // G:\k
.resolve('a/b/c', '../m'); // G:\GitHub\webpack-pure\a\b\m
- path.resolve('./'):当前运行命令所在的目录
- process.cwd():当前运行命令所在的目录
- path.sep // 平台特定的路径片段分隔符 (例如 windows 是: \ )
__dirname
:nodejs 的全局变量 返回文件所在的目录F:\work\xx\yy
__filename
:返回文件所在的目录和名称F:\work\xx\yy\file.js
获取文件名+后缀filename.slice(__dirname.length + 1)
- path.basename(
__dirname
, suffix) 返回地址的最后一部分
basename('/aa/sss/vv/') // vv
.('/aa/sss/vv') // vv
.('/aa/sss/vv.js') // vv.js
.('/aa/sss/vv.js', '.js') // vv 可用于获取文件名称
module.exports = exports = {} //是按照这个方式赋值
当先设置了 module.exports, exports.属性
将失效
require() 返回的是 module.exports
把一个对象封装到模块当中
module.exports=function(){
this.name='hew';
} //用 require 获取到的是一个函数方法
多个模块
exports.login=function(){} //用 require 获取到的是一个对象
如{
name:function{},login:function(){}
}
exports 是模块公开的接口
require 用于从外部获取一个模块接口及获取模块的 exports 对象
常见的 Content-Type
application/x-www-form-urlebcoded 常见的 form 提交 post 提交时可以将 content-type 改为该值, 传统的表单提交
multipart/form-data 不对字符编码 在对文件上传时必须使用该值,js 构建 FormData 对象,上传
application/json json 格式数据提交
text/xml 提交 xml 格式数据
Request Method
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
PUT 是修改了整条记录,不变的字段也重写,PATCH 只是修改一个字段 局部修改
OPTIONS: 询问服务器支持的方法。当浏览器发现,是一个非简单请求,就自动发出一个"预检"请求,"预检"请求用的请求方法是 OPTIONS
当 header 的 content-type 类型是以下类型时不触发 options
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
定时器
setTimeout()
setInterval()
setImmediate()
process.nextTick() 是在本轮循环执行的,所有异步任务里最先执行的
- 同步任务比异步任务早执行
- 异步任务
- 本轮循环(event loop,js 处理异步任务的方式)
- 次轮循环
- 本轮循环早于次轮循环
process.nextTick()和 Promise()的回调函数追加在本轮循环,即同步任务一旦执行完,就开始执行。
setTimeout,setInterval,setImmediate 追加在次轮循环
微任务
promise 的回调会进入异步任务的"微任务"队列
微任务队列追加在 process.nextTick 队列之后,也是属于本轮循环
只有前一个队列执行完了之后才能执行下一个队列
事件循环
https://yuchengkai.cn/docs/zh/frontend/browser.html#node-%E4%B8%AD%E7%9A%84-event-loop
事件初始化,会先完成下面事情:
同步任务
发出异步请求
规划定时器生效的时间
执行 process.nextTick()等等
事件循环会无限次地执行,只有异步任务的回调函数队列清空了,才停止。
每一轮六个阶段依次执行
timers: 执行 setTimeout 和 setInterval,他们设置的时间并不是准确的执行时间,而是到了事件后,尽快的执行,因为系统可能因为其它而被耽误 范围[1, 2147483647],不在设为 1
I/O callbacks: 执行除了 close 事件,定时器和 setImmediate 的回调
idle, prepare: idle, prepare 阶段内部实现
poll
check
close callbacks
包学习
- child_process 参见
node-koa/practice/
express
var express=require(express);
var app=express();启动一个 web 服务器,将实例赋值给一个变量叫 app
express()是 express 模块导出的一个入口函数。
koa
- koa-static 当设置的目录下有 index.html, 访问根路径时,会默认渲染 index.html
- koa-multer 处理上传的文件
- koa-bodyparser 解析上传的 json(基本)
- 使用 koa2-cors 时 要把 app.use(cors())放在最前面
- 中间件中有 next 会先执行它之前的代码,执行完最后一个中间件后会逆序执行各个中间件 next 之后的代码
graphql 实现
安装 apollo-server-koa 和 koa,看提示再安装 graphql
是一个用于 API 的查询语言,通过定义类型和类型上的字段来创建的,然后给每个类型上的每个字段提供解析函数
koa-router
- /page/:id 利用 ctx.params.id 获取
request
- ctx.request.query:获取 query string 参数 以{ key:value } 形式返回