它是一个Javascript运行环境
依赖于Chrome V8引擎进行代码解释
事件驱动
非阻塞I/O
轻量、可伸缩,适于实时数据交互应用
单进程,单线程
优点:
高并发(最重要的优点)
适合I/O密集型应用
缺点:
不适合CPU密集型应用;CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;
解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;
只支持单核CPU,不能充分利用CPU
可靠性低,一旦代码某个环节崩溃,整个系统都崩溃
原因:单进程,单线程
解决方案:(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;
(2)开多个进程监听同一个端口,使用cluster模块;
集群
单个Nodejs实例运行在单个线程中,为充分利用多核系统,需要启用一组Node进程处理负载任务。
cluster允许建立一个主进程和若干个worker进程,由主进程监控和协调worker进程的运行。
worker之间采用进程通信交换消息,cluster模块内置一个负载均衡。
开源组件库质量参差不齐,更新快,向下不兼容
Debug不方便,错误没有stack trace
ES6中声明变量的方式:
//1.使用let声明
let a = 10;
//2.使用const声明
const name = "小红";
2. var ,let , const 的区别:
不存在变量提升
变量提升
现象,即变量可以在声明之前使用,值为undefined
。不允许重复声明
作用域
{ }
内的范围常量定义的引用类型可以修改,如:
//1.使用常量定义数组
const arr = [100, 200, 300];
console.log(arr);
arr[0] = "hello";
console.log(arr); //['hello', 200, 300]
//2.使用常量来定义对象
const obj = {
name: "Jack",
age: 22,
no: "001"
}
console.log(obj);
obj.age = 100;
console.log(obj); //{name: "Jack", age: 100, no: "001"}
箭头函数
ES6 中函数式声明方式被箭头函数 => 取代
箭头函数:使用 => 定义函数
ES6中允许使用=>来定义函数。箭头函数相当于匿名函数,并简化了函数定义。
// 箭头函数
let fn = (name) => {
// 函数体
return `Hello ${name} !`;
};
// 等同于
let fn = function (name) {
// 函数体
return `Hello ${name} !`;
};
//栗子2
//普通函数
var result = [2, 4, 5, 1, 6].sort(function (a, b) {
return a - b;
});
//ES6箭头函数
var result = [2, 4, 5, 1, 6].sort((a, b) => a - b);
箭头函数在语法上比普通函数简洁多。箭头函数就是采用箭头=>来定义函数,省去关键字function。
函数的参数放在=>前面的括号中,函数体跟在=>后的花括号中
箭头函数用于回调函数,常见简洁
//栗子1
//普通函数
[1, 2, 3].map(function (x) {
return x + x;
});
//ES6箭头函数
[1, 2, 3].map(x => x + x);
箭头函数this指向
ES6 新增字符串方法
//字符串新增方法:
方法 返回值 作用
includes('str') boolean 判断字符串中包含子串
endWith('str') boolean 判断字符串以"str"结尾
startWith('str') boolean 判断字符串以"str"开头
repeat(n) 重复拼接自身 重复n次输出字符串 repeat + repeat
//不全方法: 补全字符串长度
padStart(length, s); 字符串开头补全
endStart(length, s); 字符串末尾补全
ES6 Promise 解决回调地狱
promise:为了解决异步编程中的回调地狱而产生
异步编程的一种解决方案,其实是一个构造函数,自己身上有 all、reject、resolve 这几个方法,原型上有 then、catch 等方法。
Promise的实例需要接收一个函数作为参数
该函数又需要接收两个函数数作为参数
resolve 函数
reject 函数
promise 的三种状态
pending 进行中
fullfilled 已成功 resolved 成功 执行resolve函数
rejected 已失败 rejected 失败 执行reject函数
then方法
参数一:是resolve函数的实现
参数二:是reject函数的实现
数组解构
let arr = [1, 2, 3];
//不使用数组解构
let a = arr[0];
let b = arr[1];
let c = arr[2];
//数组解构写法
let [a, b, c] = arr;
console.log(a, b, c);
对象解构
const person = {
name: "jack",
age: 21,
language: ["java", "js", "css"],
};
//普通写法
const name = person.name;
const age = person.age;
const language = person.language;
//对象解构写法
const { name, age, language } = person;
//解构后修改变量名name为abc
const { name: abc, age, language } = person;
1 2 3 4 |
|
1 2 3 4 5 6 |
|
接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
let arr = ['1', '20', '-5', '3'];
arr = arr.map((item)=>{
return item*2
});
arr = arr.map(item=> item*2);
console.log(arr); //2 40 -10 6
node 开发效率高,并有能力构建复杂系统 解决了 i/o密集 javascript 运行环境 轻量可伸缩 单线程 优点 高并发
redis 是一个支持持久化的内存数据库
缓存雪崩 由于原有缓存失效,新缓存未到期间 加锁
缓存穿透 查缓存 查数据库 布隆过滤器 拦截
数据类型 string hash list set sorted set
egg 提供定制上层框架的能力 高度可扩展插件机制(单元测试 日志中间件) 内置多线程 框架稳定 安全
express callback 回调 异常不可捕获 es5 node 的基础框架 体积大
koa web 开发框架 无回调 异步处理 健壮 es7 高级语法糖 轻量级 async await
express 和koa 区别
编程模型上的区别。Koa 的中间件是U型的,Express的中间件是线性的。
cookie 和session 的区别
cookie请求无状态 web想知道发起人服务端通过响应头 set-cookie 将少量数据响应给客户端 最后浏览器保存
session 实现基于cookie 用户session 加密后直接存储在cookie中的一个字段 用户请求 存储在服务器
传统的 session 认证
session
http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。
基于session 认证暴露的问题
1. 内存开销大
2.扩展性不强
3.csrf
token
token校验过程
用户第一次登录时,服务端生成Token并返回给客户端,保存在客户端的 localStorage
以后再访问时,需要携带token,将携带的token和在服务端保存的 token 信息进行比对校验
token缺陷
客户端每次登录时,依然需要访问数据库进行查询,并没有减轻对数据库的访问压力
jwt
用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
token 结构
头部 载荷 签证
token传递过程
token校验过程
服务端获取token后,对token进行切割,切割为三部分
对第二段密文进行 base64url 解密为明文,并获取 payload 信息,检测 token 是否已经超时?
把第1、2段密文拼接,再次执行 HS256 加密,将加密后的密文 与 使用 base64url 解密后的第3段密文进行比较,如相等,则 token 未被修改过(认证通过)
jwt 优势
1.跨语言支持
2.有了 payload 部分,JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息
3.jwt构成简单,便于传输
4.不需要在服务端保存会话信息,易于应用的扩展
docker 轻量,私密paas环境 自动化测试 持续集成部署
跨域
端口域名 协议
一、什么是跨域?
在了解跨域之前,首先要知道什么是同源策略(same-origin policy)。简单来讲同源策略就是浏览器为了保证用户信息的安全,防止恶意的网站窃取数据,禁止不同域之间的JS进行交互。对于浏览器而言只要域名、协议、端口其中一个不同就会引发同源策略,从而限制他们之间如下的交互行为:
怎么解决跨域
1.jsonp
通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。(即用JavaScript动态加载一个script文件,同时定义一个callback函数给script执行而已。)
2. 后端使用cors
//跨域问题解决方面
const cors = require('cors');
app.use(cors({
origin: ['http://localhost:8080','http://www.baidu.com'],//可设置多个跨域域名
credentials: true//允许客户端携带验证信息
}))