node.js学习笔记

node概念

Node实际上就是一个JacaScript运行环境 他集成了v8引擎,从而能对javascript代码进行解析执行

组成部分

v8 引擎 、内置API(eg:fs,path,http等模块

fs 文件系统模块

导入模块 const fs=require(‘fs’)
读文件:语法格式:fs.readFile(读取文件的路径,编码格式,function(err,results))传的参数表示失败获成功
写文件:语法格式:fs.writeFile(写入文件的路径,编码格式,回调函数)
注意

  • 内容是覆盖写入 文件夹不存在不会自动创建,会报错
  • 只能创建文件,不能创建文件路径

path路径模块

  1. 用来处理路径
  2. 引入模块 const path = require(‘path’)
  3. path.join([…paths]) ,讲多个路径拼接在一起,这里的参数表示 可以传一个或多个路径片段
  4. path.basename(路径,[.ext]) 获取到路径中的文件名
    不传入.ext 获取文件名后缀,传入ext 只获取文件名
  5. path.extname(路径) 获取路径中的文件扩展名

http模块

作用:用来创建web服务器
创建web服务器的步骤

  1. 导入 http模块
    const http= require(‘http’)
  2. 创建一个web服务器实例
    调用http.createServer()方法
  3. 为服务器实例绑定result事件
    通过 server.on(‘result’,回调函数)
  4. 启动服务器
    server.listen(3000,回调函数)

req对象和res对象

req请求对象包含请求相关信息 (请求方式,请求地址等)
res响应对象,包含响应相关信息
res.end(响应的内容)
解决相应中文乱码的问题,设置响应头:res.setHeader(‘Content-Type’,‘text/html;charset=utf-8’)

Node 模块化

概念 :将一个大文件拆分成多个独立并且相互依赖的小模块
好处 :1.提高代码的复用性
2. 提高代码的可维护性
3. 可以实现按需加载
模块化分类

  1. 内置模块 Node.js 官方提供的
  2. 自定义模块 用户创建的每个.js文件 一个js文件就是一个模块
  3. 第三方模块 第三方开发的模块

模块的加载

  1. 使用require()方法 加载需要的内置模块,用户自定义模块、第三方模块进行使用
  2. 使用require方法加载其他模块时,会执行被加载模块中的代码
  3. 在使用require加载用户自定义模块期间可以省略.js后缀名
  4. 使用require方法导入模块是,导入的结果永远以module.exports指向的对象为准
模块作用域

在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问 ,外部文件时访问不到的

模块成员

在模块中定义的变量,常量函数等都是模块的成员

对外共享模块成员

  1. 给module.exports 对象上面挂在属性
  2. 让module.exports 指向一个新对象
  3. 给exports对象上面挂在属性

安装包
npm install 包的名称(简写:npm i 包的名称)
npm i包的名称@版本 :安装指定包的版本
卸载包
npm uninstall 包的名称(简写 npm un 包的名称)
使用包的步骤

  1. 先安装包
  2. 导入包 require(‘包的名称’)
  3. 使用包

包管理配置文件(package.json)

  1. 初始化这个文件:npm init -y
  2. 注意每一个项目下面必须有一个包管理配置文件
  3. depencides节点 (记录的是项目开发和上线之后都需要用的包) 使用 npm i 包的名称|npm i 包的名称 --save(S)
  4. devdepencides 节点 (记录的是开发阶段用,项目上线之后不再使用的包)使用npm i 包的名称 --dev (-D)

模块的加载机制

一. 优先从缓存中加载
二. 内置模块的加载优先级:内置模块的加载优先级最高
三. 自定义模块的加载机制
1. 加载自定义模块 ,如果没有指定“./”或“…/”开头的路劲标识符,则node会当作内置模块或是第三方模块进行加载
2. 加载自定义模块省略扩展名的加载顺序:确切的文件名>js扩展名>json扩展名>node扩展名>加载失败,终端报错>
四. 第三方模块的加载机制
1.先从当前模块的父目录开始,从/node_modules文件中加载第三方模块
2.如果没有找到对应的第三方模块,则移动到上一层父目录中,进行加载,知道文件系统的根目录,如果还没有就会报错
五. 目录作为模块
1. 在被加载的目录下查找一个交package.json的文件,并学着main属性,作为require()加载的入口
2. 如果目录没有package.json文件或者main入口不存在或无法解析,则Node.js将会试图加载目录下的Index.js文件
3. 如果以上两步都失败了,则Node.js会在中断打印错误消息,报告模块的缺失:Error :cannot find module xxx

express框架

一、创建web服务器

  1. 导入包
    const express=require('express')
  2. 创建服务器
    const app= express()
  3. 启动服务器
app.listen('8081',()=>{
	console.log(`server is running at http://localhost:8081`)
})

二、监听get 和post 请求

  1. app.get(请求的url地址,请求对应的处理函数)
  2. app.post(请求的url地址,请求对应的处理函数)
    三、获取查询参数
    req.query 获取到的是对象
    四、获取动态参数
    req.params 获取到的是对象
    五、托管静态资源
    app.use(express.static(‘文件夹’))

express路由

概念:客户端请求和服务器处理函数之间的映射关系
定义路由的语法:app.get(url地址,请求处理函数) app.post(url地址,请求处理函数)
路由的匹配:按照定义的先后顺序进行匹配;请求类型和请求的URL同时匹配成功,才会调用对应的处理函数
路由模块化
一、定义路由

  1. 引入express
    const express=require('express')
  2. 创建路由对象
    const router=express.Router()
  3. 挂在路由
router.get('/user/list',(req,res)=>{
	res.send('get user list')
})
router.post('/login',(req,res)=>{
	res.send('post login')
})
  • 导出路由
    module.exports=router
    二、注册路由
    1.导出路由
    const router=require(' 路径 ')
    2.注册路由
    app.use('/api',router)

express中间件

一、概念
业务流程的中间处理环节是对请求的预处理
二、中间件语法格式

  • 定义中间件
const kw = function(req,res,next){
 console.log('中间件被触发了')
 //一定要加next 否则就无法执行下面的路由
 next()
}

三、全局中间件

app.use((req,res,next)=>{
	next()
})
每个请求都会经过这个中间件

四、局部中间件

//定义中间件
const kw=function(req,res,next){
	consloe.log('中间件被触发了')
}
//挂载路由
app.get('/user',kw,(req,res)=>{
	res.send('get user)
})
只有某个请求才经过中间件
定义在路由处理函数的前面
注意事项:
1.一定要在路由之前注册中间件
2.客户端发送过来的请求,可以连续调用多个中间件进行处理
3.执行完中间件的业务代码之后,不要忘记调用next()函数
4.为了防止代码逻辑混乱,调用next()函数后不要额外的代码
5.连续调用多个中间件行,多个中间件之间,共享req和res对象

五、中间件分类

  1. 应用级别的中间件 绑定到app实例上的中间件
  2. 路由级别的中间件 绑定到router实例上的中间件
  3. 错误级别的中间件
作用: 用来捕获整个项目中发生的异常,从而防止项目崩溃
格式: function(err,req,res,next){

}
注意: 错误级别的中间件,必须要注册到所有路由器之后
  1. express内置的中间件
//通过express.json()中间件,解析表单中的JSON格式的数据
app.use(express.json())
//通过express.urlencoded()中间件,会解析表单中x-www-form-urlendcoded格式的数据
app.use(express.urlencoded({extended:false}))
//express.static()中间件
  1. 第三方中间件

express编写接口

导入express
const express=require('express')
创建服务器实例
const app =express()
配置解析表单的数据
app.use(express.urlencoded({extended:false}))
导入并注册路由
const router=require('路径')
app.use('/api',router)
启动服务器

app.listen(3000,()=>{
	console.log('http://localhost:3000')
})

跨域解决方案

一、cors
概念:由一系列http响应头组成,http响应头决定浏览器是否阻止js代码跨域获取资源
实现原理:服务器端设置响应头
响应头字段
Access-Control-Allow-Origin字段

 语法: Access-Control-Allow-Origin:<origin>|*
 //origin参数的值指定了允许访问该资源的外域URL
 //限制访问资源的书写方式
 res.setHeader('Access-Control-Allow-Origin','www.baidu.com')
 //允许访问任何资源的书写方式
 res.setHeader('Access-Control-Allow-Origin','*')

Access-Control-Allow-Headers字段

//用来配置允许客户端向服务器发送额外的请求头信息
语法:
//允许客户端额外向服务器发送Content-Type请求头和X-Custom-Header请求头
//注意 多个请求头之间使用英文的逗号进行分割
res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')

Access-Control-Allow-Methods字段

//默认情况下,cors仅支持客户端发起GET,POST,HEAD请求
//用来配置允许客户端以其他的请求方式向服务器请求资源
//只允许POST,GET,DELETE,HEAD请求方法
res.setHeader('Access-Control-Allow-Methods','POST,GET,DELETE,HEAD')
//允许所有的HTTP请求方法
res.setHeader('Access-Control-Allow-Methods','*')

请求分类
简单请求
条件(同时满足)

  1. 请求方式:GET,POST,HEAD三者之一
  2. http头部信息不超过一下几个字段
  • 无自定义头部字段
  • Accept
  • Accptt-Language
  • Content-Language
  • DPR
  • Downlink
  • Save-Data
  • Viewport-width
  • width
  • Content-Type(只有三个值application/x-www-form-urlencoded、multipart/form-data、text/palin)
    特点:客户端和服务器之间只会发生一次请求

使用Mysql模块操作数据库

安装配置mysql模块

 //导入mysql模块
 const mysql=requeire('mysql')
 //建立与mysql数据库的链接
 const db=mysql.createPool({
	host:'127.0.0.1',  //数据库的ip地址
	user:'root', //登录数据库的账号
	password:'root',//登录数据库的密码
	database:'my_db_01'  //指定要操作那个数据库的名称
})

实现查询操作
const sql='select * from 数据库表名称'
实现插入操作
const sql='insert into 数据库表名称(username,password,status) values(?,?,?)'
插入便捷操作
const sql = 'insert into 数据库表名称 set ?'
实现更新操作

const user={
	username:'erdan',
	password:'123123'
}
const sql=`update 数据库表名称 set username=?,password=? where id=? `
ad.query(sql,[user.username,user.password,13],(err,results)=>{
if(err) return console.log(`sql语句执行失败:${err.message}`)
//判断更新是否成功
if(results.affectedRows===1) console.log('更新成功')
})

更新数据便捷操作

const user={
	username:'xxxx',
	password:'xxxx',
	status:1
}
//将表中的id为10的数据更新成user的数据
const sql=`update 数据库表名称 set? where id=?`
db.query(sql,[user,10],(err,results)=>{
	if(err) return console.log(`sql语句执行失败:${err.message}`)
	//判断更新是否成功
	if(results.affectedRows===1) console.log('更新成功')
})

实现删除操作

const sql= 'delete from 数据库的名称 where id=?'
db.query(sql,[user,10],(err,results)=>{
	if(err) return console.log(`sql语句执行失败:${err.message}`)
	//判断删除是否成功
	if(results.affectedRows===1) console.log('删除成功')
})

标记删除操作

const sql = 'update 数据库表名称 set status=1 where id=?'
db.query(sql,10,(err,results)=>{
	if(err) return console.log(`sql语句执行失败:${err.message}`)
	//判断删除是否成功
	if(results.affectedRows===1) console.log('删除成功')
})

身份认证

原因:http协议无状态
方式1.:服务端渲染推荐使用session做身份认证
方式2.:前后端分离的开发模式推荐使用jwt做身份认证

cookie

  • 保存在浏览器当中
  • 大小不超过4kb的字符串
  • 可以设置过期时间expires
  • 每个网站的cookie独立
  • 请求自动携带cookie
  • 不安全,可以伪造

session做身份认证
一、session的工作原理

  1. 当客户端发起登录请求,携带的账号和密码要先在服务器端做验证,如果账号密码正确,将用户信息保存在服务器内存中,会生成cookie,服务器将cookie相应给客户端,那么客户端会将cookie自动保存在浏览器中
  2. 当客户端再次发起请求,客户端会自动携带cookie,服务器获取到cookie进行认证,如果认证通过,服务器端将对应的信息响应给客户端
    Node中使用session做身份认证
    1. 下载安装express-session包
    2. 导入
    3. 进行配置,注册成中间件
    4. 在登录的接口中,登录成功保存用户信息

jwt做身份认证

工作原理

  1. 客户端去进行登录,服务器验证是否登录成功,如果成功,将用户的信息进行加密生成token字符串,响应给客户端
  2. 客户端将获取到的token保存在localStorage或者是sessionStorage
  3. 再次去发起请求,客户端要携带token 在请求投中设置一个Authorization:token
  4. 服务器将客户端发送过来的token进行解密,还原成用户对象
  5. 然后服务器进行比对,如果比对成功,就是身份认证通过,响应内容给客户端
    Node实现jwt身份认证
    1.下载安装jsonwebtoken (加密生成token字符串),express-jwt(将token字符串还原成用户信息对象)
    2.导入包
    const jwt=require('jsonwebtoken')
    const {expressjwt}=require('express-jwt')
    3.在登录的接口中,验证登录成功的化,就将用户的信息加密生成token字符串,响应给客户端
    jwt.sign(用户信息对象,加密的密钥,配置对象)
    4.解密token字符串
    配置中间件 :app.use(expressjwt({secret:xxx,xxx}).unless(path[]))
  6. 通过req.auth获取用户的信息
  7. 项目会发生奔溃,使用错误级别的中间件解决
app.use((err,req,res,next)=>{
if(err.name==='UnauthorizedError'){
	return res.send({
	status:401,
	message:'token失效'
	})
}
	res.send({
	status:500,
	message:'服务器内部发生了错误'
	})
})

res.file在配置了multer之后使用的属性,获取上传文件的信息

你可能感兴趣的:(node.js,学习,服务器)