Node实际上就是一个JacaScript运行环境 他集成了v8引擎,从而能对javascript代码进行解析执行
v8 引擎 、内置API(eg:fs,path,http等模块
导入模块 const fs=require(‘fs’)
读文件:语法格式:fs.readFile(读取文件的路径,编码格式,function(err,results))传的参数表示失败获成功
写文件:语法格式:fs.writeFile(写入文件的路径,编码格式,回调函数)
注意:
作用:用来创建web服务器
创建web服务器的步骤
req请求对象包含请求相关信息 (请求方式,请求地址等)
res响应对象,包含响应相关信息
res.end(响应的内容)
解决相应中文乱码的问题,设置响应头:res.setHeader(‘Content-Type’,‘text/html;charset=utf-8’)
概念 :将一个大文件拆分成多个独立并且相互依赖的小模块
好处 :1.提高代码的复用性
2. 提高代码的可维护性
3. 可以实现按需加载
模块化分类
在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问 ,外部文件时访问不到的
在模块中定义的变量,常量函数等都是模块的成员
安装包
npm install 包的名称(简写:npm i 包的名称)
npm i包的名称@版本 :安装指定包的版本
卸载包
npm uninstall 包的名称(简写 npm un 包的名称)
使用包的步骤
包管理配置文件(package.json)
使用 npm i 包的名称|npm i 包的名称 --save(S)
使用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
一、创建web服务器
const express=require('express')
const app= express()
app.listen('8081',()=>{
console.log(`server is running at http://localhost:8081`)
})
二、监听get 和post 请求
概念:客户端请求和服务器处理函数之间的映射关系
定义路由的语法:app.get(url地址,请求处理函数)
app.post(url地址,请求处理函数)
路由的匹配:按照定义的先后顺序进行匹配;请求类型和请求的URL同时匹配成功,才会调用对应的处理函数
路由模块化
一、定义路由
const express=require('express')
const router=express.Router()
router.get('/user/list',(req,res)=>{
res.send('get user list')
})
router.post('/login',(req,res)=>{
res.send('post login')
})
module.exports=router
const router=require(' 路径 ')
app.use('/api',router)
一、概念
业务流程的中间处理环节是对请求的预处理
二、中间件语法格式
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对象
五、中间件分类
作用: 用来捕获整个项目中发生的异常,从而防止项目崩溃
格式: function(err,req,res,next){
}
注意: 错误级别的中间件,必须要注册到所有路由器之后
//通过express.json()中间件,解析表单中的JSON格式的数据
app.use(express.json())
//通过express.urlencoded()中间件,会解析表单中x-www-form-urlendcoded格式的数据
app.use(express.urlencoded({extended:false}))
//express.static()中间件
导入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','*')
请求分类
简单请求
条件(同时满足)
安装配置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
session做身份认证
一、session的工作原理
工作原理
const jwt=require('jsonwebtoken')
const {expressjwt}=require('express-jwt')
jwt.sign(用户信息对象,加密的密钥,配置对象)
配置中间件 :app.use(expressjwt({secret:xxx,xxx}).unless(path[]))
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之后使用的属性,获取上传文件的信息