飞翔的鱼 飞翔的鱼
首页
  • Http
  • Ajax
  • Node
  • MongoDB
  • Axios
  • Git
  • Webpack
  • React
  • Vue
  • Uni-app
  • 性能优化
  • 移动端
  • HTML
  • CSS
  • stylus
  • 常用
  • 实战
  • 实用网站
  • 资源库
  • Vue专区
关于
  • css效果
  • js效果
  • 拥抱生活
  • 生活知道
GitHub (opens new window)

Wang

飞翔的鱼
首页
  • Http
  • Ajax
  • Node
  • MongoDB
  • Axios
  • Git
  • Webpack
  • React
  • Vue
  • Uni-app
  • 性能优化
  • 移动端
  • HTML
  • CSS
  • stylus
  • 常用
  • 实战
  • 实用网站
  • 资源库
  • Vue专区
关于
  • css效果
  • js效果
  • 拥抱生活
  • 生活知道
GitHub (opens new window)
  • Http

  • Ajax

  • Node

    • node
      • 为什么要学习Node.js
      • Node能做什么
      • 安装Node环境
      • 解析执行JavaScript
        • 创建Buffer
        • 转换
        • fs的使用
        • 文件的写入
        • 文件的读取
      • 模块标识符中的/和文件操作路径中的/
        • npm命令行工具
        • 常用命令
        • 解决npm被墙问题
        • yarn常用命令
      • 1.1 Express是什么
      • 1.2 Express的使用
        • 1.2.1 下载
        • 1.2.2 第一个服务器
      • 2.1 Route是什么
      • 2.2 Route的定义
      • 2.3 Route的实现
      • 2.4 Request对象
        • Request对象属性和方法
      • 2.5 Response对象
        • Response对象的属性和方法
      • 2.6 路由实例
      • 3.1中间件简介
      • 3.2中间件功能
      • 3.3 中间件的分类
      • 3.4中间件实例
        • 3.4.1应用级
        • 3.4.2内置中间件(处理request.body)
        • 暴露静态资源
      • 4.1 Router是什么
      • 4.2 为什么使用Router
      • 4.3 Router的使用
      • 5.1 使用EJS
      • 5.2 EJS语法
      • 5.3 EJS具体使用
      • 6.1art-templete的使用
      • 6.2子模板和模板的继承(模板引擎高级语法)【include,extend,block】
      • 7.1会话控制是什么
      • 7.2 cookie
        • 7.2.1 cookie是什么
        • 7.2.2 cookie的不足
        • 7.2.3 cookie的使用
      • 7.3 session
        • 7.3.1 session是什么
        • 7.3.2 session运作流程
        • 7.3.3 session的使用
        • 7.3.4 cookie和session的区别
  • MongoDB

  • Axios

  • Git

  • Webpack

  • React

  • Vue

  • Uni-app

  • 性能优化

  • 移动端

  • 前端
  • Node
wang jiaqi
2021-03-17

node

# Node介绍

# 为什么要学习Node.js

  • 企业需求
    • 具有服务端开发经验更改
    • front-end
    • back-end
    • 全栈开发工程师
    • 基本的网站开发能力
      • 服务端
      • 前端
      • 运维部署
    • 多人社区

# Node能做什么

  • web服务器后台
  • 命令行工具
    • npm(node)
    • git(c语言)
    • hexo(node)
    • ...
  • 对于前端工程师来讲,接触最多的是它的命令行工具
    • 自己写的很少,主要是用别人第三方的
    • webpack
    • gulp
    • npm

# 起步

# 安装Node环境

  • 下载:https://nodejs.org/en/

  • 确认Node环境是否安装成功

    node -v

  • 配置环境变量

# 解析执行JavaScript

  1. 创建编写JavaScript脚本文件
  2. 打开终端,定位脚本文件的所属目录
  3. 输入node 文件名执行对应的文件

注意:文件名不要用node.js来命名,也就是说除了node这个名字随便起,最好不要使用中文。

# Buffer的使用

# 创建Buffer

// 创建一个指定size大小的Buffer
var buf = Buffer.alloc(size);  //安全,里面全是0
var buf = Buffer.allocUnsafe(size);   //不安全,可能包含旧数据,需要重写所有数据

// 获取Buffer的长度
buf.length

1
2
3
4
5
6
7

# 转换

// 相当于Buffer.alloc(size);
var buf = Buffer.allocUnsafe(size);
buf.fill(0)   //将可能出现的敏感数据用0全部填充

// 将一个字符串转换为Buffer
var buf = Buffer.from(str);

// 将一个Buffer转换为字符串
var str = buf.toString();

1
2
3
4
5
6
7
8
9
10

# fs文件系统

全称为file system,所谓的文件系统,就是对计算机中的文件进行增删改查等操作。它是一个服务器的基础,在Node中通过fs模块来操作文件系统。

# fs的使用

  1. fs模块是Node的核心模块,不需要下载,直接引入即可使用
    
const fs = require("fs");
1
  1. fs中的大部分方法都为我们提供了两个版本:
    

a. 同步方法:带sync的方法

​ a) 同步方法会阻塞程序的执行

​ b) 同步方法通过返回值返回结果

b. 异步方法:不带sync的方法

​ a) 异步方法不会阻塞程序的执行

​ b) 异步方法都是通过回调函数来返回结果的

# 文件的写入

# 简单写入

同步方法:fs.writeFileSync(file, data[, options])
异步方法:fs.writeFile(file, data[, options], callback)
参数:
file 要写入的文件的路径
data 要写入的内容,可以是一个String也可以是一个Buffer
options 配置对象,需要一个对象作为参数,默认如下:
			{encoding:"utf8",flag:"w",mode:0666}
			 --encoding:设置文件的编码方式,默认值:utf8(万国码)
               --mode:设置文件的操作权限,默认值是:0o666 = 0o222 + 0o444
                     --0o111:文件可被执行的权限  
                     --0o222:文件可被写入的权限
                     --0o444:文件可别读取的权限
                 --flag:打开文件要执行的操作,默认值是'w'
                      --a :追加
                      --w :写入
callback 回调函数
	--err:错误对象
	
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//引入内置的fs模块
let fs = require('fs')

//调用writeFile方法
fs.writeFile(__dirname+'/demo.txt','kobe,123',err => {
    if(err) console.log('文件写入失败',err)
    else console.log('文件写入成功')
})
1
2
3
4
5
6
7
8

# 流式写入

流式文件写入适用于一些比较大的文件,可以分多次向文件中写入内容,有效避免内存溢出的问题

1.创建一个可写流
  var ws = fs.createWriteStream(path);
2.监听流的状态
  ws.once("open",function(){});
  ws.once("close",function(){});
3.向流中写入内容
  ws.write(...);
  ws.write(...);
  ws.write(...);
4.关闭流
  ws.end();

1
2
3
4
5
6
7
8
9
10
11
12

# 文件的读取

# 简单读取文件

fs.readFileSync(path[, options])
fs.readFile(path[, options], callback)
参数:
path 读取文件的路径
	 	options 配置对象
 		encoding 指定打开文件的编码,默认是null
 		flag 文件的操作类型,默认是 r
callback 回调函数,通过回调函数返回读取到的数据
 		    err 错误对象
 			data 返回的数据(Buffer)

1
2
3
4
5
6
7
8
9
10
11

# 流式读取文件

适合较大的文件

// 方式一:
//创建一个可读流
var rs = fs.createReadStream("C:\\other\\MP3\\笔记.mp3");
//创建一个可写流
var ws = fs.createWriteStream("biji.mp3");

//监听可读流,可读流读取完毕后会自动关闭
rs.once("open" , function () {
  console.log("流打开了");
});
rs.once("close" , function () {
  console.log("流关闭了");
//数据读取完毕,可以关闭可写流
  ws.end();
});
//监听可写流
ws.once("open" , function () {
  console.log("可写流打开了");
});
ws.once("close" , function () {
  console.log("可写流关闭了");
});
//要通过可读流读取一个文件,必须为流绑定一个data事件,当绑定了data事件以后,流会自动读取
rs.on("data",function (data) {
//console.log(data);
//将数据写入到可写流中
  ws.write(data);
});

//方式二:
//创建一个可读流
var rs = fs.createReadStream("C:\\other\\MP3\\笔记.mp3");
//创建一个可写流
var ws = fs.createWriteStream("biji.mp3");
/*
 pipe()
  - 可以将一个可读流中的内容写入到一个可写流中
 */
rs.pipe(ws);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# http

http搭建服务器服务器:

// 1.加载http核心模块
const http=require("http");

// 2.使用http.createServer()创建一个web服务器
let server=http.createServer(function (request,response) {
	response.end("ok")
})
// 4.绑定端口号,启动服务
server.listen(3000,function(){
    console.log('runing...')
})

1
2
3
4
5
6
7
8
9
10
11
12

# 模块标识符中的/和文件操作路径中的/

文件操作路径:

// 咱们所使用的所有文件操作的API都是异步的
// 就像ajax请求一样
// 读取文件
// 文件操作中 ./ 相当于当前模块所处磁盘根目录
// ./index.txt    相对于当前目录
// /index.txt    相对于当前目录
// /index.txt   绝对路径,当前文件模块所处根目录
// d:express/index.txt   绝对路径
fs.readFile('./index.txt',function(err,data){
    if(err){
       return  console.log('读取失败');
    }
    console.log(data.toString());
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14

模块操作路径:

// 在模块加载中,相对路径中的./不能省略
// 这里省略了.也是磁盘根目录
require('./index')('hello')
1
2
3

# npm,cnpm,yarn

  • node package manage(node包管理器)
  • 通过npm命令安装jQuery包(npm install --save jquery),在安装时加上--save会主动生成说明书文件信息(将安装文件的信息添加到package.json里面)

# npm命令行工具

npm是一个命令行工具,只要安装了node就已经安装了npm。

npm也有版本概念,可以通过npm --version来查看npm的版本

升级npm(自己升级自己):

npm install --global npm
1

# 常用命令

npm init -y   //可以跳过向导,快速生成
1
npm install   //一次性把dependencies选项中的依赖项全部安装
npm i		  //简写
1
2
npm install 包名   //下载第三方包
1
npm install --save 包名   //下载并且保存依赖项(package.json文件中的dependencies选项)
1
npm uninstall 包名  		//只删除,如果有依赖项会依然保存
1
npm uninstall --save 包名   //删除的同时也会把依赖信息全部删除
1

# 解决npm被墙问题

###1.国内使用npm存在的问题

npm的远程服务器在国外,所以有时候难免出现访问过慢,甚至无法访问的情况。

npm config get registry    //查看当前npm远程仓库地址
1

###2.使用淘宝的cpm代替npm

####第一种使用方法:直接安装cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org
1

####第二种使用方法:替换npm仓库地址为淘宝镜像地址

npm config set registry https://registry.npm.taobao.org   
1

###3.使用yarn代替npm

npm install yarn -g    //全局安装yarn
1

####第二种使用方法:替换yarn仓库地址为淘宝镜像地址

yarn config set registry https://registry.npm.taobao.org
1

# yarn常用命令

yarn --version   		//查看yarn版本

yarn init 				//生成package.json  !!!注意生成的包名不能有中文,大写

yarn global package     //全局安装  

yarn add package 	    //局部安装

yarn add package --dev  //相当于npm中的--save-dev

yarn remove package     //移除包

yarn list 				//列出已经安装的包名

yarn info package       //获取包的有关信息

yarn 					//安装package.json中的所有依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# path路径操作模块

参考文档:https://nodejs.org/docs/latest-v13.x/api/path.html

  • path.basename:获取路径的文件名,默认包含扩展名
  • path.dirname:获取路径中的目录部分
  • path.extname:获取一个路径中的扩展名部分
  • path.parse:把路径转换为对象
    • root:根路径
    • dir:目录
    • base:包含后缀名的文件名
    • ext:后缀名
    • name:不包含后缀名的文件名
  • path.join:拼接路径
  • path.isAbsolute:判断一个路径是否为绝对路径image-20200315150610001

# Node中的其它成员(__dirname,__filename)

__dirname		//可以用来**动态**获取当前文件模块所属目录的绝对路径
1
__filename		//可以用来**动态**获取当前文件的绝对路径(包含文件名)
1

在拼接路径的过程中,为了避免手动拼接带来的一些低级错误,推荐使用path.join()来辅助拼接

var fs = require('fs');
var path = require('path');
// console.log(__dirname + 'a.txt');
// path.join方法会将文件操作中的相对路径都统一的转为动态的绝对路径
fs.readFile(path.join(__dirname + '/a.txt'),'utf8',function(err,data){
	if(err){
		throw err
	}
	console.log(data);
});
1
2
3
4
5
6
7
8
9
10

# 第1章:Express简介

# 1.1 Express是什么

Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供一系列强大的特性,帮助你快速创建各种 Web 和移动设备应用。

简单来说Express就是运行在node中的用来搭建服务器的模块。

# 1.2 Express的使用

# 1.2.1 下载

npm i express --save  //使用npm安装express并添加到依赖项
yarn add express	 //使用yarn安装express并添加到依赖项
1
2

# 1.2.2 第一个服务器

//1.引入express模块
const  express=require("express")
//2.创建应用对象
const app = express()
//3.配置路由
app.get("/index",function (request,response) {
     //接受地址栏发送的请求,格式为对象
    console.log(request.query)
    //设置响应
	response.send("ok")
})
//4.监听端口
app.listen(3000,function () {
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 第2章:路由(Route)

# 2.1 Route是什么

路由是指如何定义应用的端点(URIs)以及如何响应客户端的请求。

路由是由一个 URI、HTTP 请求(GET、POST等)和若干个句柄组成的。

# 2.2 Route的定义

我们可以将路由定义为三个部分:

第一部分:HTTP请求的方法(get或post)

第二部分:URI路径

第三部分: 回调函数

# 2.3 Route的实现

Express中提供了一系列函数,可以让我们很方便的实现路由:

app.<method>(path,callback)    
//method指的是HTTP请求方法,比如:  app.get()  app.post(),express中app.all()方法,可以处理两种请求
//path指要通过回调函数来处理的URL地址  
//callback参数是应该处理该请求并把响应发回客户端的请求处理程序  
1
2
3
4

# 2.4 Request对象

# Request对象属性和方法

**属性/**方法 描述
request.query 获取get请求查询字符串的参数,拿到的是一个对象
request.params 获取get请求参数路由的参数,拿到的是一个对象
request.body 获取post请求体,拿到的是一个对象(要借助一个中间件)
request.get(xxxx) 获取请求头中指定key对应的value

# 2.5 Response对象

# Response对象的属性和方法

**属性/**方法 描述
response.send() 给浏览器做出一个响应
response.end() 给浏览器做出一个响应(不会自动追加响应头)
response.download() 告诉浏览器下载一个文件
response.sendFile() 给浏览器发送一个文件
response.redirect() 重定向到一个新的地址(url)
response.set(header,value) 自定义响应头内容
response.get() 获取响应头指定key对应的value
res.status(code) 设置响应状态码

# 2.6 路由实例

const express = require("express")
let app = express()
app.get("/", function (request, response) {
    //接受地址栏发送的请求,格式为对象
    // console.log(request.params);
    //console.log(request.params)
    //response.send("ok")
    // response.download("./demo.zip")
    // response.redirect("https://www.baidu.com")
})
app.listen(3000, function () {
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11
12
13

# 第3章:中间件

# 3.1中间件简介

概念:本质上就是一个函数,包含三个参数:request、response、next

# 3.2中间件功能

  1. 执行任何代码。
    
  2. 修改请求和响应对象。
    
  3. 终结请求-响应循环。
    
  4. 调用堆栈中的下一个中间件。
    

# 3.3 中间件的分类

1)	应用(全局)级中间件(过滤非法的请求,例如防盗链)
              --第一种写法:app.use((request,response,next)=>{})
              --第二种写法:使用函数定义
2)	第三方中间件,即:不是Node内置的,也不是express内置的(通过npm下载的中间件,例如body-parser)
              --app.use(bodyParser.urlencoded({extended:true}))
3)	内置中间件(express内部封装好的中间件)
              --app.use(express.urlencoded({extended:true}))
              --app.use(express.static('public')) //暴露静态资源
4)	路由器中间件 (Router)
1
2
3
4
5
6
7
8
9

# 3.4中间件实例

# 3.4.1应用级

const express = require("express")
let app = express()
/*【第一种】使用应用级(全局)中间件------所有请求的第一扇门
-------所有请求都要经过某些处理的时候用此种写法*/
app.use((request,response,next)=>{
    response.send("全局中间件")
    next()   //跳过此中间件,到下一个中间件或下一个路由
})
app.get("/", function (request, response) {
   response.send("index")
})
app.get("/login", function (request, response) {
    response.send("login")
})
app.get("/register", function (request, response) {
    response.send("register")
})
app.listen(3000, function () {
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//第二种写法:使用函数定义
const express = require("express")
let app = express()
function guard(request,response,next){
    response.send("函数中间件")
    
}
app.get("/", function (request, response) {
   response.send("index")
})
//在此路由上添加中间件,就不会拦截所有的路由了,guard是自己定义的函数
app.get("/login", guard,function (request, response) {
    response.send("login")
})
app.get("/register", function (request, response) {
    response.send("register")
})
app.listen(3000, function () {
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 3.4.2内置中间件(处理request.body)

const express = require("express")
let app = express()
// 解析post请求请求体中所携带的urlencoded编码形式的参数为一个对象,随后挂载到request对象上
app.use(express.urlencoded({extended:true}))
app.get("/", function (request, response) {
   response.send("index")
})

app.post("/login",function (request, response) {
    console.log(request.body)
    response.send("login")
})
app.get("/register", function (request, response) {
    response.send("register")
})
app.listen(3000, function () {
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 暴露静态资源

const express = require("express")
let app = express()
//将public中的静态文件暴露出去,避免了使用多个路由
app.use(express.static(__dirname+"/public"))
app.get("/", function (request, response) {
   response.send("index")
})

app.listen(3000, function () {
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11

# 第4章:Router路由器

# 4.1 Router是什么

Router 是一个完整的中间件和路由系统,也可以看做是一个小型的app对象。

# 4.2 为什么使用Router

为了更好的分类管理route

# 4.3 Router的使用

//创建路由器
const {Router}=require("express")
let router=new Router()
//使用路由
router.app("/",()=>{})
router.use()
1
2
3
4
5
6

# 第5章:EJS模板

EJS是一个高效的 JavaScript 模板引擎,动态渲染数据,使得前后端分离,是基于express的

# 5.1 使用EJS

使用ejs前必须有express模版

  1. 下载安装
    
npm i ejs -S
yarn add ejs -S
1
2
  1. 配置模板引擎
    
app.set("view engine" , "ejs")
1
  1. 配置模板的存放目录(目录为后面的)
    
app.set("views","./views")
1
  1. 在views目录下创建模板文件
    

模板名称.ejs

  1. 使用模板,通过response来渲染模板
    

response(‘模板名称’, 数据对象)

# 5.2 EJS语法

ejs语法: 1.< % % > 里面能写任意js代码,但是不会向浏览器输出任何东西。 2.< %- % > 能够将后端传递过来对象指定key所对应value渲染的页面,渲染html标签 3.< %= % > 能够将后端传递过来对象指定key所对应value渲染的页面不渲染html标签

# 5.3 EJS具体使用

server.js

const express=require("express")
const app=express()
//配置模版引擎
app.set("view engine","ejs")
//配置模版路径
app.set("views","./views")
app.get("/",(req,res)=>{

    res.render("index",{data:"hello"})
})
app.listen(3000,()=>{
    console.log("run")
})
1
2
3
4
5
6
7
8
9
10
11
12
13

index.ejs

<%-data%>
1

# 第6章:art-templete模版的使用

在node中,有很多第三方模板引擎都可以使用,不是只有art-template,还有ejs,jade(pug),handlebars,nunjucks

# 6.1art-templete的使用

npm install --save art-template
npm install --save express-art-template

//1.两个一起安装
npm i --save art-template express-art-template
//2.引用art-template模版,第一个参数设置后缀名  
app.engine('html', require('express-art-template'));
//3.使用art-template
app.get('/',function(req,res){
// express默认会去views目录找index.html(如果希望修改默认的`views`视图渲染存储目录,可以使用app.set('views',目录路径)来修改,第一个参数views千万不要修改;)
    res.render('index.html',{
           title:'hello world'     
    });
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 6.2子模板和模板的继承(模板引擎高级语法)【include,extend,block】

模板页:

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>模板页</title>
	<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css"/>
	{{ block 'head' }}{{ /block }}
</head>
<body>
	<!-- 通过include导入公共部分 -->
	{{include './header.html'}}
	
	<!-- 留一个位置 让别的内容去填充 -->
	{{ block  'content' }}
		<h1>默认内容</h1>
	{{ /block }}
	
	<!-- 通过include导入公共部分 -->
	{{include './footer.html'}}
	
	<!-- 公共样式 -->
	<script src="/node_modules/jquery/dist/jquery.js" ></script>
	<script src="/node_modules/bootstrap/dist/js/bootstrap.js" ></script>
	{{ block 'script' }}{{ /block }}
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

模板的继承:

​ header页面:

<div id="">
	<h1>公共的头部</h1>
</div>
1
2
3

​ footer页面:

<div id="">
	<h1>公共的底部</h1>
</div>
1
2
3

模板页的使用:

<!-- 继承(extend:延伸,扩展)模板也layout.html -->
<!-- 把layout.html页面的内容都拿进来作为index.html页面的内容 -->
{{extend './layout.html'}}

<!-- 向模板页面填充新的数据 -->
<!-- 填充后就会替换掉layout页面content中的数据 -->
<!-- style样式方面的内容 -->
{{ block 'head' }}
	<style type="text/css">
		body{
			background-color: skyblue;
		}
	</style>
{{ /block }}
{{ block 'content' }}
	<div id="">
		<h1>Index页面的内容</h1>
	</div>
{{ /block }}
<!-- js部分的内容 -->
{{ block 'script' }}
	<script type="text/javascript">
		
	</script>
{{ /block }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 第7章:会话控制

# 7.1会话控制是什么

HTTP协议是一个无状态的协议,它无法区分多次请求是否发送自同一客户端。

# 7.2 cookie

# 7.2.1 cookie是什么

关于cookie:

​ 1.是什么?

​ 本质就是一个【字符串】,里面包含着浏览器和服务器交互的信息。

​ 存储的形式以:【key-value】的形式存储。

​ 浏览器会自动携带该网站的cookie,只要是该网站下的cookie,全部携带。

  1. 分类:

    会话cookie(关闭浏览器后,会话cookie会自动消失,会话cookie存储在浏览器运行的那块【内存】上)。

    持久化cookie:(看过期时间,一旦到了过期时间,自动销毁,存储在用户的硬盘上,备注:如果没有到过期时间,同时用户清理了浏览器的缓存,持久化cookie也会消失)。

3.工作原理:

​ 当浏览器第一次请求服务器的时候,服务器可能返回一个或多个cookie给浏览器,当浏览器以后请求该网站的时候,自动携带上该网站的所有cookie(无法进行干预),并判断cookie种类,服务器拿到之前自己“种”下cookie,分析里面的内容,校验cookie的合法性,根据cookie里保存的内容,进行具体的业务逻辑。

4.应用:

​ 解决http无状态的问题(一般来说不会单独使用cookie,一般配合后台的session存储使用)

5.不同的语言、不同的后端架构cookie的具体语法是不一样的,但是cookie原理和工作过程是不变的。

备注:cookie不一定只由服务器生成,前端同样可以生成cookie,但是前端生成的cookie几乎没有意义。

# 7.2.2 cookie的不足

各个浏览器对cookie的数量和大小都有不同的限制,这样就导致我们不能在Cookie中保存过多的信息。一般数量不超过50个,单个大小不超过4kb。

cookie是由服务器发送给浏览器,再由浏览器将cookie发回,如果cookie较大会导致发送速度非常慢,降低用户的体验。

# 7.2.3 cookie的使用

在node中express库下使用cookie

1.创建cookie

const express=require("express")
const  app=express()
//创建一个回话cookie(cookie必须以键值对的字符串传递)
app.get("/demo1",(req,res)=>{
    let obj={name:"zhangsan"}
    res.cookie("data",JSON.stringify(obj))
    res.send("创建一个回话cookie")
})
//创建一个持久化cookie
app.get("/demo2",(req,res)=>{
    let obj={name:"lisi"}
    res.cookie("data",JSON.stringify(obj),{maxAge:1000*60})
    res.send("创建一个持久化cookie")
})
app.listen(3000,()=>{
    console.log("run")
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

2.读取cookie,需要借助第三方中间件 cookie-parser

//下载cookie-parse
npm i cookie-parser --save
1
2
const express=require("express")
//引入cookie-parser
const cookieParser = require("cookie-parser")
const  app=express()
//配置cookieParser
app.use(cookieParser());
//接受浏览器返回的cookie(不区分会话和持久化)
app.get("/demo3",(req,res)=>{
    let {data}=req.cookies   //注意接收的是req.cookies(不是cookie)
    console.log(JSON.parse(data))
    res.send("返回cookie到服务器的控制台")
})
app.listen(3000,()=>{
    console.log("run")
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

3.修改和删除cookie

res.cookie("data","hahha");   //可以使用同名的cookie来替换已有cookie
res.cookie("data","",{maxAge:0});   //value为空,maxAge为0
res.clearCookie(“data”)       //用来删除一个指定cookie
1
2
3

# 7.3 session

# 7.3.1 session是什么

1.是什么?

​ 后端人员常常把【session会话存储】简称为:session

2.特点:

​ 1.存在于服务端

​ 2.存储的是浏览器和服务器之间交互产生的一些信息

3.默认session的存储在服务器的内存中,每当一个新客户端发来请求,服务器都会新开辟出一块空间,供session会话存储使用。

4.工作流程:

​ (1)第一次浏览器请求服务器的时候,服务器会开辟出一块内存空间,供session会话存储使用。返回响应的时候,会自动返回一个cookie(有时候会返回多个,为了安全),cookie里包含着会话存储的编号(id)

​ (2)浏览器以后请求的时候,会自动携带这个cookie,给服务器。服务器从该cookie中拿到对应的session的id,去服务器中匹配。

​ (3)服务器会根据匹配信息,决定下一步逻辑

5.备注:

​ 1.一般来说cookie一定会配合session使用。

​ 2.服务端一般会做session的持久化,防止由于服务器重启,造成session的丢失。

​ 3.session什么时候销毁?

​ (1).服务器没有做session的持久化的同时,服务器重启了。

​ (2).给客户端种下的那个用于保存session编号的cookie销毁了,随之服务器保存的session销毁(不管是否做了session的持久化)。

​ (3).用户主动在网页上点击了“注销” “退出登录”等等按钮。

# 7.3.2 session运作流程

我们可以在服务器中为每一次会话创建一个对象,然后每个对象都设置一个唯一的id,并将该id以cookie的形式发送给浏览器,然后将会话中产生的数据统一保存到这个对象中,这样我们就可以将用户的数据全都保存到服务器中,而不需要保存到客户端,客户端只需要保存一个id即可。

# 7.3.3 session的使用

  1. 下载安装
    
npm i connect-mongo express-session --save
1
  1. 引入模块
    
var session = require("express-session");
1
  1. 将其配置为express-session的默认的持久化仓库
    
var MongoStore = require('connect-mongo')(session);
1
  1. 设置为中间件
    
app.use(session({
  name: 'id22',   //设置cookie的name,默认值是:connect.sid
  secret: 'atguigu', //参与加密的字符串(又称签名)
  saveUninitialized: false, //是否为每次请求都设置一个cookie用来存储session的id
  resave: true ,//是否在每次请求时重新保存session
  store: new MongoStore({
    url: 'mongodb://localhost:27017/test-app',
    touchAfter: 24 * 3600 // 24小时之内只修改一次
  }),
  cookie: {
    httpOnly: true, // 开启后前端无法通过 JS 操作
    maxAge: 1000*30 // 这一条 是控制 sessionID 的过期时间的!!!
  },
}));
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 7.3.4 cookie和session的区别

  1. 存在的位置:
    

cookie 存在于客户端,临时文件夹中

session 存在于服务器的内存中,一个session域对象为一个用户浏览器服务

  1. 安全性:
    

cookie是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放

session存放于服务器的内存中,所以安全性好

  1. 网络传输量:
    

cookie会传递消息给服务器

session本身存放于服务器,但是通过cookie传递id,会有少量的传送流量

  1. 生命周期(以20分钟为例):
    

cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束

session的生命周期是间隔的,从创建时,开始计时如在20分钟,没有访问session,那么session生命周期被销毁;但是,如果在20分钟内(如在第19分钟时)访问过session,那么,将重新计算session的生命周期;关机会造成session生命周期的结束,但是对cookie没有影响

  1. 访问范围:
    

session为一个用户浏览器独享

cookie为多个用户浏览器共享

  1. 大小:
    

cookie 保存的数据不能超过4K,很多浏览器都限制一个站点最多保存50个cookie

session 保存数据理论上没有任何限制(内存有多大就能有多大)

编辑 (opens new window)
#n#o#d#e# #-
上次更新: 2021/07/01, 20:33:02
ajax
mongodb

← ajax mongodb→

最近更新
01
数组常用方法
05-21
02
边框
04-30
03
js1
04-29
更多文章>
Theme by Vdoing | Copyright © 2021-2021 本博客仅仅作为自己日常学习记录笔记使用
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×