同学们好,我是连颜少,一个菜鸟前端,都说前端要掌握一门后端语言,才能更好的理解前后端的交互,这里我就记录下我初学NODE的一些笔记,希望对同学们有点帮助~
fs模块:
//被[,]包裹起来的为可选参数
const fs = require('fs')
fs.readFile(path[,option],callback)
path: //文件路径
option://编码格式:默认为utf-8
callback(err,dataStr)://文件读取完成后,通过回调函数读取的结果
成功:err = null;
失败: dataStr = undefined;
fs.writeFile(file,data[,option],callback)
file://文件路径
data://写入内容(覆盖写入)
option://编码格式:默认为utf-8
callback(err,dataStr)://文件读取完成后,通过回调函数读取的结果
成功:err = null;
.// / 或者 ../ 相对路径会出现问题
//解决:提供完整的文件路径,__dirname 当前所处的文件路径
__dirname + 'files/1.txt'
path模块:
path.join([...paths]): //将多个路径片段拼接
paths://多个路径片段
返回值:string
path.join(__dirname,'files/1.txt')
path.basename(path,'扩展名'): //从路径字符串中,将文件名解析出来
path: //地址
返回值://文件名.扩展名
path.extname(path)://获取文件扩展名
http模块:创建web服务器模块
http.createServer()
server.on('request',(req,res) => {})
req //包含一系列内容
req.url
req.method
res //包含一系列内容
res.setHeader('Content-Type','text/html';'charset=utf-8'): //设置编码方式,否则中文乱码
res.end(content) //方法结束本次请求,并返回内容
server.listen(80,() => {}) //默认地址127.0.0.1 默认端口80
//模块内变量只能在模块内使用
每个js文件都有一个module变量,都有一个exports对象,当通过require导入的时候,返回的内容就是exports,exports最终指向也是module.exports
导入模块的时候,会执行模块
module.exports = {
XXX : XXX,
aaa : function() {}
}
npm安装小知识
npm i bao -D 开发依赖包,会被记录在devDependencies;
npm i bao 核心依赖包,记录在dependencies节点下;
require优先从缓存机制中加载
内置模块优先级最高,当第三方模块名和node内置模块名重复,默认加载node内置模块
加载自定义模块需要相对路径
当没有后缀的时候,node默认按顺序尝试加载.js => .json => .node
express
- express 的作用和nodejs内置的http模块相似,是专门用来创建web服务器的
- express 的本质是一个npm第三方包,提供了快速创建web服务器的便捷方法
-
web网站服务器
-
api接口服务器
express创建服务器
const express = require('express')
const app = express()
app.listen(80,() => {
console.log(express server running at 80 port)
})
app.get('/',function(req,res) {
console.log('req.query',req.query) // 匹配?a=1示例参数
console.log('req.param',req.params)//匹配:id示例动态参数
})
express静态资源入口
// express.static:创建一个静态资源服务器
app.use(express.static('public')) //所有地址都可以访问
app.use('/public',express.static('./files')) //只有当访问public开头的接口的时候,才能访问public下的文件
// public不会出现在路径当中
// 当挂载多个静态服务器,从先声明的文件中找,找到就返回
express中的路由挂载
//作用:处理客户端请求和服务端处理函数之间的映射关系
//模块路优化步骤:
//在router.js文件中
//1.导入express
const express = require('express')
//2.创建路由对象
const router = express.Router()
//3.挂在具体的路由
router.get('/user/list',fuunction(req,res) {
res.send('GET LIST SUCCESS')
})
//4.向外导出路由对象:所有module对外导出都通过module.exports,导入文件才能接收到对象
module.exports = router
//在服务器文件中
//1.导入router.js 自定义模块
const router = require('./router.js')
//2.挂在到express服务器上
app.use(router)
app.use('/api',Router) //统一的路由前缀
中间件函数(五大类)
- 1.中间件函数:需要定义在路由之前,从上到下执行
- 2.通过next()结束该中间件函数
应用级别中间件:app.use / app.get / app.post绑定
// 1.全局中间件
app.get('/',function(req,res,next){
next()
})
const mv = function(req,res,next) {
next()
}
//使用全局中间件函数
app.use(mv)
//或者
app.use(function(req,res,next){
next()
})
//2.局部中间件:在路由调用的时候,作为第二个参数传入 ,mv只在 /user 地址下生效
app.get('/user',mv,function(res,req) {
})
//3.多个局部中间件
app.get('/user',mv1,mv2,function(res,req) {
})
//或者
app.get('/user',[mv1,mv2],function(res,req) {
})
- 1.中间件函数之间是共享req和res,对req和res的修改会影响到其他的中间件函数
- 2.定义多个中间件,都用app.use()进行注册,并按照注册的顺序依次执行中间件
路由级别中间件:在router.js中,绑定在router下:router.use / router.get / router.post
错误级别中间件:放在所有路由之后
//抓门用来捕获整个项目发生的错误,防止项目崩溃
//必须四个形参(err,req,res,next) 顺序固定
//ps:认为制造报错方法:throw new Error('xxxxx')
app.use(function(err,res,req,next) {
res.send('Error!' + err.message)
})
Express内置的中间件
express.static:访问文件
express.json:解析json格式请求体数据
app.use(express.json())
express.urlencoded(extended:false)
app.use(express.urlencoded({extended:false}))
第三方的中间件
//示例
const = qs = require('querystring')
app.use((req,res,next) => {
// 监听数据传输,并拼接字符串
let str = '';
req.on('data',(chunk) => {
str += chunk
})
// 当请求数据接受完毕,会自动处罚req的end事件
req.on('end',() => {
// 解析数据
const body = qs.parse(str)
req.body = body
next()
})
})
跨域问题CORS
使用cors中间件解决跨域问题:相当于配置了Access-Control-Allow-* 请求头
npm i cors //安装中间件
const cors = require('cors')
app.use(cors())
CORS能配置请求头包括:
Accept / Accept-Language / Content-Language / DPR / Downlink / Save-Data / Viewport-Width / Width / Content-Type(text/plain,multipart/form-data,application/x-www-form-urlencoded三者之一)
res.setHeader('Access-Control-Allow-Origin',<origin> | *)
默认只允许发送GET,POST,HEAD请求,希望发送其他请求需要配置
res.setHeader('Access-Control-Allow-Methods','POST,GET,DELETE,PUT,HEAD') 或者 *
预检请求:
只要复合以下的任何一请求,都需要进行预检请求:客户端和服务器之间会发生两次请求,OPTION预检请求成功之后,才会发起真正的请求
- 1.请求方式为GET,POST,HEAD之外的Method类型
- 2.请求头中包含自定义头部字段
- 3.向服务器发送了application/json格式的数据
认证机制(两种)
服务端渲染推荐Session认证机制
~服务端渲染推荐Session认证机制:
1.HTTP协议的无状态性:客户端每次HTTP请求都是独立的
2.身份认证方式:cookie
cookie:存储在浏览器中不超过4KB的字符串,由NAME,Value,Domain,path,expires,httpOnly等组成,控制cookie的有效期,安全性,使用范围
当客户端发起请求,会自动,自动!!将当前域名下,所有未过期的cookie一起发送到服务器端
~客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的cookie,客户端会自动将cookie保存至浏览器中
~之后,客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的cookie,通过请求头的形式发送给服务器,服务器即可验证客户端的身份
cookie不具有安全性,浏览器提供读写cookie的api,可以伪造cookie,也可以从cooike中读取隐私数据
前后端分离推荐使用JWT认证机制
Session认证
//安装express-session中间件
npm i express-session
//配置express-session
const session = require('express-session')
app.use(session({
secret:'keyboard car', // secret属性值可以是任意字符串
resave:false, //固定写法
saveUninitialized:true //固定写法
}))
// 配置成功后,req就会多一个session对象,
// 请求登录后,存储登录用户信息及状态在session中,之后请求的接口中,req中会一直有之前保存的session对象
app.post('/api/login',(req,res) => {
//判断用户提交的信息是否正确
if (req.body.username !== 'admin' || req.body.password !== '123456') {
return res.send({status:1,msg:'login fail'})
}
//保存信息到session中
req.session.user = req.body
res.session.islogin = true
res.send({
status:0
msg:'login success'
})
})
// 之后的接口中:
app.get('/api/username',(req,res) => {
//从session中取值,判断是否登录,或者判断用户类型,返回对应内容
if (!req.session.islogin) {
return res.send({status:1,msg:'fail'})
}
res.send({status:0,msg:'success',user:req.session.user})
})
//退出登录后,清空session信息
app.post('/api/logout',(req,res) => {
//清空当前客户端对应的session信息
req.session.destory()
res.send({
status:0
msg:'logout success'
})
})
JWT认证机制(JSON Web Token):目前最流行的跨域认证解决方案
sequenceDiagram
客户端->>服务器: 客户端登录,提交账号及密码
服务器->>客户端: 服务器响应,验证密码,加密生成Token字符串返回给客户端
客户端->>服务器: 客户端将Token存储到localStorage或者SessionStorage,之后请求都通过请求体的Authorization字段,将Token返回
服务器->>客户端: 服服务器接受Token,解密认真身份,响应当前用户对应内容再返回给客户端
JWT的组成部分
1.Header(请求头).Payload(有效荷载).Signature(签名),用'.'隔开
2.Payload 部分才是真正的用户信息,通过加密后生成的字符串
3.把JWT放在HTTP的请求头Authorization中
4.Authorization: Bearer <token> (拼接)
在express中使用JWT
npm i jsowebtoken // 用于生成JWT字符串
npm i express-jwt // 将JWT字符串解析还原成JSON对象
const jwt = require('jsonwebtoken')
const expressJWT = require('express-jwt')
//定义secret秘钥
//1.当生成JWT字符串的时候,需要使用secret秘钥对用户的信息进行加密,最终得到加密好的JWT字符串
//2.把JWT字符串解析还原成JSON对象的时候,需要使用同一个secret秘钥进行解密
const secretKey = 'lys No1~~'
app.post('/api/login',function(req,res) {
//当登录成功的时候
res.send({
status:200,
messgae:'login success',
token:jwt.sign({username:userinfo.username},secretKey,{expiresIn:'30s'})
})
})
//3.解析token
app.use(expressJWT({secret:secretKey}))
// unless({path:[正则]}) //规定哪些接口不需要验证token
//4.当配置成功express-jwt,接口的req参数中会多一个user变量,把解析出来的内容放在req.user里面
//捕捉JWT解析失败后产生的错误:在express错误中间件中,根据错误去判断
app.use((err,req,res,next) => {
//token 错误解析
if(err.name === 'UnauthorizedError') {
return res.send({status:'401',message:'无效token'})
}
//其他错误原因
res.send({})
})
其他精彩:
- 一篇学会Array原型里的所有方法
- 一篇掌握Object原型里的所有方法
- 初识Vue3,带你认识Vue2和Vue3的区别(一)
- 妈妈说,不会Vue3会被人看不起的(二)
- 奇怪的原型链冷知识(需要有一定原型链的基础才能看哦)
- vue图片放大器,相册集:vue-photo-preview
- 手摸手教你从0用echart写一个响应式页面