💥此MD/PDF/HTML文档由 @竹梦者也编辑制作,不可贩卖❌。仅供学习交流使用,下载后切勿随意传播。转载麻烦加上出处~

📌欢迎在留言区提供修改建议~

💌本文内容和代码来自于tianyu老师的Node教程

 

✅2021.7.12 @竹梦者也(https://www.zjgsuzjx.top)

✅2021.7.18 更新v1.1,完善了模块化内容

 

一、Node.js一、基本使用1. 概念2. 特点3. 与浏览器端区别4. 安装5. 环境配置6. 用Node运行JS二、模块化1. 概念2. CommonJS# 浏览器端3. ES6模块化# 暴露# 引入# 进阶使用# Babel4. AMD模块化5. CMD模块化三、包和包管理器1. package包# 包结构# 包描述文件# 创建一个包2. NPM# 作用# 常用指令3. cnpm# 概念# 安装4. Yarn# 概念# 特点# 安装# 修改Yarn的全局安装和缓存位置# 常用指令四、Buffer缓冲器1. 概念2. 使用# 第一种# 第二种# 第三种3. 数据存入实例五、fs文件系统1. 概念2. 使用# 简单文件的写入# 流式文件写入# 简单文件读取# 流式文件读取二、数据库一、基本概念1. 含义2. 用途3. 分类# 关系型数据库(RDBS)# 非关系型数据库(NoSQL)二、MongoDB1. 简介2. 安装3. 安装图形化工具4. Navicat使用教程5. MongoDB的使用# 简介# 基本命令# 操作命令6. 数据库的CRUD7. Mongoose# 简介# 优势# 使用# CRUD8. mongoose的模块化三、Express一、原生Node服务器1. 服务器搭建2. 服务器响应二、Express使用1. 概念2. 下载3. 搭建服务器4. Route路由# 概念# 组成部分# 实例# Request对象# Response对象5. 中间件# 简介# 功能# 分类# 应用层中间件# 第三方中间件# 内置中间件# 注册登录页面案例# Router路由器三、EJS模板1. 概念2. 安装与使用四、cookie1. 概念2. 分类3. 工作原理4. 应用5. 简单使用五、session1. 概念2. 特点3. 工作流程4. 数据加密# md5# sha1

 

一、Node.js

一、基本使用

1. 概念

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。

c958254e333bb78272c98b9835dbdd04.png

使得让JS代码在本地也能运行,从而能够操作本地的文件。原理是将JS代码转译为C/C++代码,从而能够实现socket(网络编程)、http、文件系统、etc(编译环境)、事件循环模型、异步操作。

2. 特点

优点

1) 异步非阻塞的I/O(I/O线程池)

2) 特别适用于I/O密集型应用(频繁I/O操作)

3) 事件循环机制

4) 单线程(成也单线程,败也单线程)

5) 跨平台

缺点

1) 回调函数嵌套太多、太深(俗称回调地狱)

2) 单线程,处理不好CPU 密集型任务(Java解决高并发是提升配置,Node解决高并发是用回调函数;CPU每个请求太慢时,会造成Node排队时间过长)

CPU密集型与I/O密集型的区别:

CPU密集型:需要过多的判断,事情不明确。

I/O密集型:不需要过多的判断,事情明确。

3. 与浏览器端区别

浏览器端:js由BOM、DOM、ES规范组成。

Node端:js只由ES(所有规范)和global(Node内置属性,相当于window)组成。

4. 安装

https://nodejs.org/zh-cn/

左边是正式服,右边是测试服。

安装完成之后,打开命令行窗口,输入node -v查看当前node版本。

5. 环境配置

https://www.cnblogs.com/zhouyu2017/p/6485265.html

环境配置的目的是为了在cmd中能够直接使用指令。如node、yarn等等。

6. 用Node运行JS

方法1

在cmd里,cd到JS文件所在文件夹。再输入node xxx.js

方法2

打开我的电脑到指定文件夹,在路径中直接输入cmd并回车,后面跟上面同理。

方法3

在webstorm里配置好node环境,直接右键运行js文件。

File ---> Settings ---> Languages & Frameworks ---> Node.js and NPM

方法4

按住shift + 右键,点击在此处打开命令行。再输入node xxx.js

二、模块化

1. 概念

模块化指的就是将一个大的功能拆分为一个一个小的模块,通过不同的模块的组合来实现一个大功能。

Node中使用的是CommonJS规范来实现的模块化,前端使用的模块化规范是AMDCMD

2. CommonJS

CommonJS 是一套模块化规范,它包含:模块、二进制、Buffer、字符集编码、I/O流、进程环境、文件系统、套接字、单元测试、Web服务器网关接口、包管理等。

补充:CommonJS是唯一一个可以在双端(浏览器、node)运行的模块化规范。

补充2:服务器端模块的加载时同步的。

补充3:暴露的本质是module.exports所指向的那个对象

在CommonJS模块规范中,module.exportsexports.xxx不能混用。如果混用则以module.exports为主。

9511253dbb927fdc02293da0d76475cc.png

模块引用

通过require()函数来引入外部的模块。

它需要一个模块的标识作为参数,返回一个对象表示引入的模块

补充:在引入的同时可以解构赋值。

注意:引入第三方模块时,直接写包名;引入自定义模块时,要写路径。

模块使用

模块暴露的是一个对象,所以在使用时就当作对象来使用,如:

模块定义

1) 在node中一个js文件就是一个模块

2) 在node中每一个模块中的代码都是运行在一个独立的函数中的,

3) 默认情况下模块内部代码对于外部来说都是不可见的,可以通过两种方式向外部暴露变量和函数

a.可以通过将变量函数设置为 exports 的属性来暴露变量和函数

b.也可以通过module.exports来向外部暴露变量和函数

模块标识

1) 引入外部模块时,需要通过模块的标识进行引入

2) 对于自定义的文件模块,模块的标识就是文件的路径(绝对路径、以 . 或 .. 开头的相对路径)

例子:"./a" "../b"

3) 对于下载的模块或系统模块模块的标识就是文件的名字如"fs" "express"

module.exports和exports的区别

exports变量是对moduleexports属性的引用,我们在向exports中添加属性时,本质上是在向module.exports中添加属性。module.exports 可以直接通过赋值的形式来暴露内容。exports 不能直接赋值,只能通过.的形式添加属性

如果是简单的暴露属性,使用exports就好,引入模块使用方式:m1.属性名

如果需要向外暴露一个构造函数,使用module.exports,引入模块使用方式:m1

node中的函数

输入以下代码在node用运行。

会出现:

这个函数是所有模块都有的,node编译时往其中注入5个参数:

exports 暴露模块

require 引入模块

module exports属性暴露模块

__filename 文件的绝对路径

__dirname 文件夹的绝对路径

# 浏览器端

在浏览器端有特殊的目录要求。index页面是必须的。

浏览器不认识require。需要借助第三方包browserify

安装npm install -g browserify

执行browserify (输入文件路径) -o (输出文件路径),注意路径问题。

浏览器没有引入的先后顺序。

3. ES6模块化

只支持浏览器端。

共有三种暴露方式,分别暴露、统一暴露、默认暴露。

# 暴露

分别暴露

统一暴露

默认暴露

# 引入

备注:分别暴露和统一暴露使用频率较少,因为有命名冲突

# 进阶使用

备注:暴露可以混着用,引入时默认暴露必须排在前面。

# Babel

浏览器不认识ES6的模块化语法。需要一个第三方包Babel。可以将ES6语法转成ES5语法,并且将jsx语法转为js语法。

全局安装:npm install babel-cli browserify -g

局部安装:npm install babel-preset-es2015 -D

创建.babelrc文件:在根目录下创建,内容如下:

命令:babel (输入文件夹路径) -d (输出文件夹路径)

browserify (输入文件路径) -o (输出文件路径)

备注:成功后还会自动启动严格模式。

4. AMD模块化

全称Asynchronous Module Definition(异步模块定义)。

专门用于浏览器端,模块的加载是异步的。

需要require.js文件。https://requirejs.org/

基本语法

html引入

总结:很老的项目还在用

5. CMD模块化

阿里自己写的模块,全称Common Module Definition()

基本语法

汇总

使用sea.js

输出顺序为:2---1---4---3

三、包和包管理器

1. package包

Node.js的包基本遵循CommonJS规范,包将一组相关的模块组合在一起,形成一组完整的工具。

举例:类似电脑上的一个文件夹,包含了某些特定的文件,并且符合某些特定的结构,就是一个包。

包由包结构和包描述文件两个部分组成。

1) 包结构:用于组织包中的各种文件

2) 包描述文件:描述包的相关信息,以供外部读取分析

# 包结构

包实际上就是一个压缩文件,解压以后还原为目录。符合CommonJS规范的目录,应该包含如下文件:

1) package.json 描述文件(必要

2) bin 可执行二进制文件(可选)

3) lib js代码(可选)

4) doc 文档(可选)

5) test 单元测试(可选)

# 包描述文件

包描述文件用于表达非代码相关的信息,它是一个JSON格式的文件:package.json

包描述文件包含以下字段:nameversiondescriptionkeywordsmaintainerscontributorsbugslicensesrepositoriesdependencies(生产依赖)、homepageoscpuenginebuiltindirectoriesimplementsscriptsauthorbinmaindevDependencies(开发依赖)。

# 创建一个包

输入命令:npm init

包名要求:不能有中文、大写字母、尽量不能与其它包同名。

2. NPM

全称:Node Package Manager , Node的包管理器。

# 作用

通过NPM可以对Node的包进行搜索、下载、安装、删除、上传。

# 常用指令

搜索npm search xxxx;或者www.npmjs.com

安装npm install xxxx -g(全局安装)== 等同于npm i xxxx -g

npm install xxxx -D(安装包并写入到开发依赖中)

注意开发依赖生产依赖的区别:写代码时才用到的库,就是开发依赖;项目上线给其它人用时的库,就是生产依赖,如jquery等等。

npm i xxx@x.x.x(安装x.x.x版本的包)

npm i(安装package.json中声明的所有包)

移除npm remove xxx(在node_module中删除xxx包,同时删除package.json声明)

其它npm view xxxx versions(查看npm仓库中xxx包的所有版本信息)

npm ls xxxx(查看当前安装的xxx包的版本)

3. cnpm

# 概念

它是淘宝对国外npm服务器的一个完整镜像版本,也就是淘宝 NPM 镜像。可以加速下载。

https://npm.taobao.org/

# 安装

第一种

直接安装:安装淘宝提供的cnpm,并更改服务器地址为淘宝的国内地址。

npm install -g cnpm --registry=https://registry.npm.taobao.org,以后安装可以直接采用cnpm代替npm。

缺点:会造成npm和cnpm两种指令共存,会有bug。

第二种

替换npm仓库地址为淘宝镜像地址(推荐)。

命令:npm config set registry https://registry.npm.taobao.org,查看是否成功:npm config get registry

4. Yarn

# 概念

yarn是Facebook开源的新的包管理器,可以用来代替npm

# 特点

有缓存;没有自己的仓库地址,使用的是npm仓库地址。

# 安装

npm install yarn -g

# 修改Yarn的全局安装和缓存位置

在CMD命令行中执行

在我们使用全局安装包的时候,会在“D:\Software\yarn\global”下生成 node_modules\bin目录

我们需要将D:\Software\yarn\global\node_modules\.bin 整个目录添加到系统环境变量中去,否则通过yarn添加的全局包 在cmd中是找不到的。

检查当前yarn的bin的位置:yarn global bin

检查当前yarn的全局安装位置:yarn global dir

随后跟配置npm一样配置环境变量。

# 常用指令

yarn global add xxxx(全局下载指定包)

yarn global remove xxxx(删除全局依赖包)

yarn info xxxx(查看某个包的信息)

yarn init -y(初始化项目)

四、Buffer缓冲器

1. 概念

2. 使用

一共有三种创建方式。

# 第一种

备注:性能特别差。特点是在堆里开辟空间,同时会清理要回收的空间为己用。

# 第二种

备注:性能比new Buffer()稍强一点。特点是在堆中开辟一段空间,且这个空间没有被使用过。

# 第三种

备注:性能最好。特点是在堆里随意开辟空间,可能是别人用过的。

问题

为什么输出的不是二进制?

输出的是16进制,但是存储的是二进制,输出的时候会自动转换为16进制

为什么第三种输出的不为空?

在堆里开辟空空间,可能残留着别人用过的数据。

3. 数据存入实例

输出的16进制,可以用bf.toString()方法转为字符串。之所以是16进制,是因为存入的不一定是字符串,也可以是媒体文件如视频、音乐等等。

五、fs文件系统

1. 概念

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

2. 使用

fs模块是Node的核心模块,不需要下载,直接引入即可使用。

fs中的大部分方法都为我们提供了两个版本:

同步方法:带sync的方法

同步方法会阻塞程序的执行;同步方法通过返回值返回结果。

异步方法:不带sync的方法

异步方法不会阻塞程序的执行;异步方法都是通过回调函数来返回结果的。

# 简单文件的写入

语法

file:要写入的文件路径+文件名+后缀

data:要写入的数据

options:配置对象(可选参数)

--encoding:设置文件的编码方式,默认值: 'utf8' --mode:设置文件的操作权限,默认值: 0o666 --flag:打开文件要执行的操作。 默认值: 'w'。 --signal:允许中止正在进行的写入文件

callback:回调函数

err:错误对象

例子

# 流式文件写入

语法

path:要写入文件的路径+文件名+文件后缀

options;配置对象(可选参数)

--flags:同上 --encoding:同上 -fd:文件统一标识符,Linux下文件标识符 --mode:同上 --autoClose:自动关闭--文件,默认值:true --emitClose:关闭-—-文件,默认值:true --start:写入文件的起始位(偏移量)

例子

# 简单文件读取

语法

path:要读取文件的路径+文件名+后缀

options:配置对象(可选)

callback:回调

例子

简单文件写入和简单文件读取,都是一次性把所有要读取或要写入的内容加到内存中,容易造成内存泄露。

# 流式文件读取

语法

path:要读取文件的路径+文件名+后缀 options:同上 --flags:同上 --encoding:同上 --fd:同上 --mode:同上 --autoClose:同上 --emitclose:同上 --start:起始偏移量 --end:结束的偏移量 --highwaterMark:每次读取数据的大小,默认是64*1024

例子

边读边写的流失例子

二、数据库

一、基本概念

1. 含义

数据库(DataBase)是按照数据结构来组织、存储和管理数据的仓库。

2. 用途

我们的程序都是在内存中运行的,一旦程序运行结束或者计算机断电,程序运行中的数据都会丢失。所以我们就需要将一些程序运行的数据持久化到硬盘之中,以确保数据的安全性。而数据库就是数据持久化的最佳选择。

说白了,数据库就是存储数据的仓库。

3. 分类

# 关系型数据库(RDBS)

代表有MySQL(⭐,轻量)、Oracle(⭐,甲骨文)、DB2SQL Server(微软,大学上课才用)

特点:关系紧密,都是表

386c1628cac70025eb3ef0261307ef44.png

优点

1、易于维护:都是使用表结构,格式一致

2、使用方便:通用,可用于复杂查询(全是SQL语句)

3、高级查询:可用于一个表以及多个表之间非常复杂的查询

缺点

1、读写性能比较差,尤其是海量数据的高效率读写

2、有固定的表结构,字段不可随意更改,灵活度稍欠

3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈

举例

# 非关系型数据库(NoSQL)

代表有MongoDBRedis(高速缓存,大数据用)

特点:关系不紧密,有文档,有键值对

ef3804bc68296afaab581adbd5f6908b.png

优点

1、格式灵活:存储数据的格式可以是key,value形式

2、速度快:nosql可以内存作为载体,而关系型数据库只能使用硬盘

3、易用:nosql数据库部署简单

缺点

1、不支持sql(结构化查询语句),学习和使用成本较高

2、不支持事务(ACID特性,所以不能用于支付交易)

3、复杂查询时语句过于繁琐

二、MongoDB

1. 简介

MongoDB是为快速开发互联网Web应用而设计的数据库系统。

MongoDB的设计目标是极简、灵活、作为Web应用栈的一部分。

MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据库中存的是各种各样的JSON。(BSON)

2. 安装

最新社区版https://www.mongodb.com/try/download/community

教程https://www.jianshu.com/p/e963d0e0bb94

或者https://blog.csdn.net/yuxiaohe1/article/details/111317947

4.4以上已经自动配置好开机自动启动了,无需另外配置

3. 安装图形化工具

studio3t:https://studio3t.com/download/(需要破解)

Navicat Premium 15:http://www.navicat.com.cn/download/navicat-premium(需要破解,破解教程https://mp.weixin.qq.com/s/g2myLey2Of0V0_YqwvnWpQ

4. Navicat使用教程

https://www.jb51.net/article/206956.htm

在导航栏处的查询按钮可以使用编辑器,有代码高亮和提示,支持多行语句运行。

查看->显示隐藏项目 可以显示被隐藏的数据库

da779c6f4666b9c5ee66f7a34cecd296.png

5. MongoDB的使用

# 简介

数据库(database):数据库是一个仓库,在仓库中可以存放集合。

集合(collection):集合类似于JS中的数组,在集合中可以存放文档。说白了,集合就是一组文档。非常类似于JSON,因此称为BSON

4f0fcfa42b0602b76a46fd00aef92680.png

文档(document):文档数据库中的最小单位,我们存储和操作的内容都是文档。类似于JS中的对象,在MongoDB中每一条数据都是一个文档。

c44065c7bdd3f213c881193fcba8335d.png

# 基本命令
# 操作命令

MongoDB数据库集合都不需要创建,当我们向集合或数据库中第一次插入文档时,集合和数据库会自动创建

db.stus.insert({name:"sunwukong",age:18})

db.stus.find()

6. 数据库的CRUD

CRUD指的是数据库的增删改查(create、delete、update、read)。

查询网址: https://docs.mongodb.com/manual/reference/method/js-collection/

-C create(新增数据)

db.集合名.insert(文档对象)

db.集合名.insertOne(文档对象)

db.集合名.insertMany([文档对象,文档对象])

如:

insertinsertOne的底层代码是一样的

-R read(查询数据)

db.集合名.find(查询条件[,投影])

举例:

db.students.find({age:18}),查找年龄为18的所有信息类例

db.students.find({age:18,name:'jack"}),查找年龄为18且名字为jack的学生

投影:过滤掉不想要的数据,只保留想要展示的数据。_id比较特殊,要单独写。

db.students.find({},{_id:0,name:0}),过滤掉id和name

db.students.find({},{age:1}),只保留age

补充db.集合名.findOne(查询条件[,投影]),默认只要找到到一个,提高效率。

常用操作符

举例:db.集合名.find({age:{$gte:20}}),年龄是大于等于20的

查找年龄为18或20的学生

举例:db.students.find({age:($in:[18,20]}})

举例:db.students.find(($or:[{age:18},{age:20}]})

举例:db.students.find({age:{$nin:[19,17]}}),不是19也不是17

举例:db.students.find({name:/^T/}),查找所有T开头的名字

-U update(更新数据)

db.集合名.update(查询条件,要更新的内容[,配置对象])

// 如下写法会将更新内容替换掉整个文档对象,但_id不受影响,慎用

举例:db.students.update({name:'zhangsan'},{age:19})

// 使用$set修改指定内容,其他数据不变,不过只能匹配一个

举例:db.students.update({name:'zhangsan"},{$set:{age:19}})

// 修改多个文档对象,匹配多个,把所有匹配到的年龄都替换为19

举例:db.students.update((name:'zhangsan'},{$set:{age:19}},{multi:true})

补充:db.集合名.updateOne(查前条件,要更新的内容(,配置对象])

db.集合名.updateMany(查询条件,要更新的内容[,配置对象])

-D delete(删除数据)

db.集合名.remove(查询条件)

// 删除所有年龄小于等于19的学生 举例:db.students.remove({age:($lte:19}})

7. Mongoose

# 简介

Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。

mongoDB:一个数据库品牌的名字

mongod:启动数据库的命令

mongo:连接数据库的命令

mongoose:Node平台下,一个知名的用于帮助开发者连接mongoDB的包

# 优势
# 使用

下载

yarn global add mongoose或者npm i mongoose -g

连接

# CRUD

-C create(新增数据)

没有数据库时,会自动创建,其中__v是mongo自带的。成功后的图如下:

c77bdcb5a41f0d06007c19080ab0c047.png

之后记得右键刷新数据库。

b210d7878ea94a76c7a7766287c3bfd6.png

-R read(查询数据)

-U update(更新数据)

-D delete(删除数据)

投影

注意:规则执行过一次之后,只会越来越严格,无法变宽;Mongo提供了字符串自动转译功能,但是对于无法转数字的字符串还是会报错的。

8. mongoose的模块化

app.js

db.js

studentModel.js

由于回调函数是在最后执行的,所以不能直接反馈。所以要通过这种回调函数传参、暴露函数的方法来实现模块化,也可以用promise来实现,但还没学习。

三、Express

一、原生Node服务器

1. 服务器搭建

2. 服务器响应

运行服务器之后,在浏览器输入http://127.0.0.1:3000/?name=zhangsan&age=18,会出现hello world!zhangsan你好世界!18

二、Express使用

1. 概念

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

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

2. 下载

npm i express -g

3. 搭建服务器

4. Route路由

# 概念

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

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

# 组成部分

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

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

第二部分:URI路径

第三部分:回调函数

# 实例

可以配合html的form表单来测试:

# Request对象

Request对象是路由回调函数中的第一个参数,代表了用户发送给服务器的请求信息。要先引入express

通过Request对象可以读取用户发送的请求包括URL地址中的查询字符串中的参数,和post请求的请求体中的参数。

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

参数路由有特殊语法:

# Response对象

Response对象是路由回调函数中的第二个参数,代表了服务器发送给用户的响应信息。

通过Response对象可以设置响应报文中的各个内容,包括响应头和响应体。

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

备注:若有多个响应则以 response.send为主

5. 中间件

# 简介

中间件(Middleware) 是一个函数,它可以访问请求对象(request), 响应对象(response), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。

补充:银行系统和安全系统等需要安全功能的场合会大量使用中间件。

# 功能

1) 执行任何代码。

2) 修改请求和响应对象。

3) 终结请求-响应循环。(让一次请求得到响应)

4) 调用堆栈中的下一个中间件或路由。

# 分类

1) 应用级(全局)中间件(过滤非法的请求,例如防盗链)

--第一种写法:app.use((request,response,next)=>{})

--第二种写法:使用函数定义

2) 第三方中间件(通过npm下载的中间件,例如body-parser

3) 内置中间件(express内部封装好的中间件)

4) 路由器中间件 (Router

# 应用层中间件

备注:以上代码要在app.js里。不是来自端口号63347就不给通过。

优化方案

好处:这就是中间件的含义。只有请求该地址的时候才会做出判断,避免了很多无用功的判断。

# 第三方中间件

需要下载一个中间件npm i body-parser -g

由此就可以用body拿到post请求过来的数据。

# 内置中间件

不用使用body-parser,只要加上这一句express内置的方法。就可以实现上面例子的结果。

暴露静态资源可以把所有该目录下的html页面交出去,比如http://loaalhost:3000/meishi.html,就可以访问public目录下的meishi.html。

# 注册登录页面案例

校验数据的合法性:(一般是前台后台同时验证

1.校验成功 ->去数据库中查找该邮箱是否法册过 法册过:提示用户邮第已被占用。 未注册:写入数据库

2.校验失败 ->提示用户具体哪里输入的不正确

server.js:

login.html:

register.html:

后端和前端验证是必要的,因为前端验证可以有办法跳过。

注意业务路由(处理逻辑)和UI路由(展示页面)的区别。

# Router路由器

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

为了更好的分类管理route(类比于路由器和端口的概念)

使用Router改注册登录页面案例

UIRouter.js

loginRegisterRouter.js

server.js

备注

  1. 中间件本质是一个函数,所以在接口暴露的时候必须要暴露一个函数,然后在函数内部返回对象。
  2. Node的内置path模块专门要来解决路径的问题。

三、EJS模板

1. 概念

EJS是一个高效的 JavaScript 模板后端引擎。

简单来说,使用EJS模板引擎就能动态渲染数据。art-template是前端模板引擎。

2. 安装与使用

下载:npm i ejs -g

基础使用:

index.js:

person.ejs:

ejs语法

备注:这是前后端不分离的情况,就是前端语句和后端语句杂糅在一起了,非常不友好。日后趋势是前后端分离。

使用ejs改注册登录页面案例:(只以登录为例子)

登录的业务路由

备注:JSON.stringify可以将对象转译成JSON字符串

login.ejs

四、cookie

1. 概念

本质就是一个字符串,里面包含着浏览器和服务器沟通的信息(交互时产生的信息)。

存储的形式以:key-value的形式存储。

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

2. 分类

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

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

3. 工作原理

  1. 当浏览器第一次请求服务器的时候,服务器可能返回一个或多个cookie给浏览器。
  2. 浏览器判断cookie种类: 会话cookie:存储在浏览器运行的那块内存上 持久化cookie:存储在用户的硬盘上
  3. 以后请求该网站的时候,自动携带上该网站的所有cookie(无法进行干预)
  4. 服务器拿到之前自己“种”下cookie,分析里面的内容,校验cookie的合法性,根据cookie里保存的内容,进行具体的业务逻辑。

4. 应用

解决http无状态的问题(例子:7天免登录,一般来说不会单独使用cookie,一般配合后台的session存储使用)

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

5. 简单使用

备注:express中读取客户端携带过来的cookie要借助一个中间件,名为:cookie-parser

利用cookie完善登录和个人中心页面

UI路由.js(部分)

业务路由.js(部分)

五、session

1. 概念

标准来说,session这个单词指的是会话。

前端通过浏览器去查看cookie的时候,会发现有些cookie的过期时间是:session,意味着该cookie是会话cookie

后端人员常常把session会话存储简称为:session存储,或者更简单的称为:session

2. 特点

存在于服务端;存储的是浏览器和服务器之间沟通产生的一些信息

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

3. 工作流程

  1. 第一次浏览器请求服务器的时候,服务器会开辟出一块内存空间,供session会话存储使用
  2. 返回响应的时候,会自动返回一个cookie(有时候会返回多个,为了安全),cookie里包含着,上一步产生会话存储“容器”的编号(id)
  3. 以后请求的时候,会自动携带这个cookie,给服务器
  4. 服务器从该cookie中拿到对应的sessionid,去服务器中匹配
  5. 服务器会根据匹配信息,决定下一步逻辑

注意

  1. 一般来说cookie一定会配合session使用。
  2. 服务端一般会做session持久化,防止由于服务器重启,造成session的丢失。

session什么时候销毁?

  • 服务器没有做session的持久化的同时,服务器重启了。
  • 给客户端种下的那个用于保存session编号的cookie销毁了,随之服务器保存的session销毁(不管是否做了session的持久化)。
  • 用户主动在网页上点击了“注销” “退出登录”等等按钮。

用session完善登录和个人中心页面

server.js(服务器部分)

业务逻辑部分.js

UI逻辑部分.js

备注:为了操作session并且持久化,需要两个中间件。express-sessionconnect-mongo

小知识📌:很多主流网站只要将你的个人页面cookie全部导出,就可以用这个cookie来登录网站。但只要有一方退出,服务器session就会消失。

4. 数据加密

为了安全性要对数据库的重要信息进行加密,比如用户注册时的密码。

目前常用的数据加密技术有md5sha1。(sha1md5略强)

# md5

安装npm i md5 -g

使用

# sha1

安装npm i sha1 -g

使用