1.什么是Node?
node是一个基于Chrome v8引擎的js代码运行环境
2.Node的组成
ECMAScript+Node.js的API
3.Node.js模块化开发:
Node.js规定一个js就是一个模块,模块内部定义的变量和函数默认情况下在外部是无法得到的。
模块成员的两种导出方式:
第一种:
使用exports对象进行成员导出,使用require方法进行模块导入
第二种:
使用module.exports对象进行成员导出,使用require方法进行模块导入。
4.Node.js系统模块:
- 文件操作 fs
- 路劲操作 path
- 创建服务器 http
- 地址请求参数 url
- 将post的参数转换为对象 querystring
系统模块的使用:
1.File(文件操作)
// callback接受两个参数,err,doc. err读取成功返回null,doc是读取文件的内容
fs.readFile(路径','utf-8',callback)
//callback接受一个参数,err err==null代表文件写入成功,如果文件不存在则自动创建文件
fs.writeFile('路径',‘内容’,callback)
2.Path(路径操作)
path.join('路径1',‘路径2’) // 路径拼接
path.join(__dirname,'路径') // __dirname获取文件的绝对路径
3.http(创建服务器)
var app=http.createServer(); 创建一个服务器
4.Url(解析请求参数)
1.请求的路径 2.将参数转换为对象形式
url.parse(req.url,true) //获取请求地址的参数
5.querystring ( 将post的参数转换为对象)
querystring.parse()
5.第三方模块:
如何使用第三方模块:
npm install 模块名 //安装
npm uninstall 模块名 //卸载
1.nodemon(热编译模块)
npm install nodemon -g // 全局安装
在命令工具中代替node命令就可以实现热编译。
2.nrm (切换镜像)
npm install nrm -g
查询地址 nrm ls
切换npm下载地址 nrm use 切换的地址’
3.gulp(打包第三方模块)
1.使用npm install gulp 下载gulp文件
2.在项目根目录下简历gulpfile.js文件夹
3.重构项目的文件夹解构,src放置源代码文件,dist目录放置构建后文件。
4.在gulpfile.js文件中编写任务。
5.在命令工具中执行gulp任务
4.mongoose (链接mongodb数据库)
1.npm install mongoose
2.创建链接
3.建立集合规则
4.插入数据
5.art-template(模板引擎)
1.npm install art-template
2.引入模板 const template=require('art-template')
3.template('路径',{data:{name:'xy'}})
6.router(实现路由)
1.获取路由对象
2.调用路由对象提供的方法创建路由
3.启用路由,使路由生效
const getRouter=require('router');
const router=getRouter();
router.get('/add',(req,res)=>{
res.end('Hello World!')
})
server.on('request',(req,res)=>{
router(req,res)
})
7.serve-static(静态资源访问)
const serveStatic=require('serve-static')
const serve=serveStatic(path.join(__dirname,'public'))
8.dateformat(时间处理)
//引用第三方模块
const dateFormat = require('dateformat');
// 向模板内部导入dateFormate变量
template.defaults.imports.dateFormat = dateFormat;
// 在模板中使用
<td>{{dateFormat($value.publishDate, 'yyyy-mm-dd')}}</td>
9.express框架
express的特点:
1.提供了方便的路由
2.更加方便的获取到请求参数
3.提供了中间件有效控制http请求
10.body-parse ( 获取express框架中post参数)
const bodyParser = require('body-parser');
//对body-parser进行配置
app.use( bodyParser.urlencoded({extended: true}) )
//设置完毕之后,会在req对象上面新增一个req.body的一个对象
11.bcrypt(对密码进行加密)
哈希加密是单进程的加密方式 1234=>abcd
在加密的密码中加入随机字符串可以增加密码被破解的难度
1.导入bcrypt模块
const bcrypt=require('bcrypt')
生成随机字符串
let salt=await bcrypt.genSalt(10)
使用随机字符串对密码进行加密
let pass=await brcypt.hash('明文密码',salt)
2.密码比对
let isEqual=await bcrypt.compare('明文密码','加密的密码(数据库中查出来的)')
bcrypt依赖其他环境
1.python 2.x
2.node-gyp
npm install -g node-gyp
3.windows-build-tools
npm install --global --production windows-build-tools
12.express-session (将用户信息存储到session中)
1.npm install express-session
2.引入const session=require('express-session')
配置session
3.app.use(session({secret:'secret key'}))
4.在req对象里面添加用户信息
req.session.user=user.usernam
13.Joi(对数据进行格式校验)
1.const Joi=require('Joi')
2.const Schema={
//alphanum-> username只能是字母字符串,或者数字字符串
username:Joi.string().alphanum().min(3).max(30).required().error(new Error('错误信息'))
password:Joi.string().regex(/[a-zA-Z0-9]{3,30}$/)
// 接收一个数组,里面可以使字符串也可以是整数
access_token:[Joi.string(),Joi.integer()],
// 接收一个number,必须是整型
birthyear:Joi.number().integer().min(1900).max(2013),
email:Joi.string().email(),
// 字段默认值
role:Joi.string().valid('admin','normal').required()
}
3.验证规则,第一个参数是验证的对象,第二个是规则对象
Joi.validate({username:'abc',birthyear:1994},Schema)
14.formidable(解析二进制表单信息,包含图片文件上传)
1.npm install formidable
2.引入formidable
const formidable=require('formidable')
3.创建表单解析对象
const form=new formidable.IncomingForm();
4.设置文件上传路径
form.uploadDir="/my/dir"
5.是否保留表单上传文件的扩展名
form.keepExtensions=true (上传服务器的文件必须要保留扩展名)
6.form.parse(req,(err,fields,files)=>{
// err存储失败信息
// fields 存储普通请求参数
// files 存储上传的文件信息
})
15.mongoose-sex-page (进行分页)
1.npm install mongoose-sex-page
2.const pagination=require('mongoose-sex-page')
// page当前页 size每页显示数据条 display当前显示的页码数 exec向数据库发送请求
3.pagination(集合构造函数).page(1).size(20),display(10),exec()
4.查询结构返回一个对象,里面有页码,总页数等等。
6.使用gulp
gulp方法:
gulp.src() 获取任务要处理的文件
gulp.dest() 输出文件
gulp.task() 建立gulp任务
gulp.watch() 监控文件的变化
gulp常用插件
gulp-htmlmin: html文件压缩
gulp-csso 压缩css
gulp-babel es语法转换
gulp-less less语法转换
gulp-uglify 压缩混淆js代码
gulp-file-include 公共文件包含 //npm install gulp-babel @babel/core @babel/
7.package.json的详解:
package.json是当前项目描述信息,例如项目版本号、作者.依赖的第三方模块等等。使用npm init -y 生成。
8.Node.js中模块加载机制:
- 1.require根据引用的路劲,如果是完整路径直接引入模块
- 2.如果模块后缀省略,找同名的js文件再找同名js文件夹
- 3.如果找到同名文件夹找到里面的index.js
- 4.如果没有index.js那么就去package.js里面找到main入口文件
9.创建一个服务器:
// 用于创建服务器
const http=require('http')
// 网站服务器对象
const app=http.createServer()
// 添加事件
app.on('request',(req,res)=>{
// req里面保存了请求的相关信息
// res是响应的相关信息
res.end('Hello User
')
})
// 监听端口号
app.listen(3000)
10.请求报文
1.req.headers 获取请求报文信息
2.req.url 获取请求地址
3.req.method 获取请求方法
11.回调函数
回调函数就是用函数作为参数传递,在回调中可以接收到函数传递过来的参数。
function fn(callback){
setTimeout(()=>{
callback({result:'回调结果'})
},2000)
}
fn(function(result){
console.log(result)
})
12.异步函数:async
1.普通函数定义前加async关键字,普通函数变成异步函数。
2.异步函数默认返回promise对象
3.在异步函数内部使用return关键字进行结果返回,结果会被包裹的promise对象中,return代替了resove方法
4.在异步函数中使用throw关键字抛出错误
5.在调用异步函数再链式调用then方法获取异步函数执行结果
6.调用异步函数再链式调用catch方法获取异步函数执行的错误信息。
13:异步函数:await
1.await关键字只能出现在异步函数中
2.await后面只能写promise对象。
3.await关键字可以暂停异步函数向下执行,直到promise返回结果。
14.
mongodb连接数据库:
1.npm install mongoose
2.启动mongodb
3.引入模块
mongoose.connect('mongodb://localhost/数据库名字').then().catch()
//4.设置集合规则
const courseSchema=new mongoose.Schema({})
//5.创建集合
const course=mongoose.model('Course',courseSchema)
//6.插入数据
course.create({})
15.mongodb导入数据:
1.添加mongodbimport 命令到系统path环境中去
mongoimport -d 数据库名 -c 集合名 --file 导入文件
2.mongoimport -d shop_app -c user --file .\user.json
16.mongodb常用操作方法:
默认查询语句会把_id这个字段查询出来,如果你不需要查询某个字段加-
0.查询name,age字段,不查询_id
user.find().select('nage age -_id')
1.查询age=22
user.find({'age':22})
2.查询age>22
user.find({'age':{$gt:20}})
3.查询age<22
user.find({'age':{$lt:22}})
4.查询age>=22
user.find({'age':{$gte:22}})
5.查询age<=22
user.find({'age':{$lte:22}})
6.查询age >= 23 并且 age <= 26
user.find({age:{$gte:23,$lte:26}})
7.查询name中包含 mongo的数据
user.find({name:/mongo/})
8.查询name中以mongo开头的
user.find({name:/^mongo/})
9.查询指定列name、age数据
user.find({},{name:true,age:true})
user.find().select('name age')
10.查询指定列name、age数据, age > 25
user.find({age:{$gt:25},{name:true,age:true}})
11.按照年龄排序
user.find().sort({age:1})
user.find().sort({age:-1})
12.查询name = zhangsan, age = 22的数据
user.find({name:'zhangsan',age:'22'})
13.查询前5条数据
user.find().limit(5);
14.查询10条以后的数据
user.find().skip(10)
15.查询在5-10之间的数据
user.find().limit(10).skip(5)
16.or与 查询
user.find({age:{$or:[{age:20},{age:32}]}})
17.查询第一条数据
user.findOne();
18.查询某个结果集的记录条数
user.findOne({age:{$gt:25}}).count()
19.存在age字段的数据
user.find({age:{$exists:true}})
20.查询当前总数:
user.countDocuments({})
17.删除文档
删除一个满足条件(删除成功返回)
user.findOneAndDelete({}).then(res=>{console.log(res)})
删除多个(如果传递的是空对象{},会删除这个集合所有的内容)
user.deleteMany({}).then()
18.更新操作:
更新一个
user.updateOne({name:'猫九'},{name:'猫十'})
更新多个
user.updateMany({},{name:'猫十'})
19.mongodb验证规则
name:{
type:String, 类型
required:true, 毕传字段
maxlength:20, 字符串最大长度
min:2, 数值最小为2
max:100, 数值虽大为100
enum:['html','css','java'], 枚举 列举出当前字段可有用的值范围
trim:true,去除两边空格
default:'abc' 默认值
}
20.集合关联
const User=mongoose.model('User',new mongoose.Schema({name:{type:String}}))
文章集合
const Post=mongoose.model('Post',new mongoose.Schema(
{title:{type:String}},
author:{type:mongoose.Schema.Types.Object,ref:'User'}))
联合查询
Post.find().populate('author').then(res=>{console.log(res)})
1.模板引擎:
模板引擎是一个第三方模块,能更加友好的将html和数据进行拼接。
1.下载并引入模板引擎:
npm install art-template
const template=require('art-template')
2.使用模板引擎,就收两个参数,第一个是路径(文件路径),第二个是一个对象(数据)
路径必须是绝对路径
2.模板语法:
标准语法:
输出: {{}}
{{a?a:b}}
{{a+b}}
原始语法:
输出: <%= %>
<%= a?a:b %>
<%= a+b %>
3.原文输出:
如果返回的数据中带有html标签,模板引擎默认是不解析的。可以使用原文标签进行输出。
标准语法:
{{@name}}
原始语法:
<%- %>
4.条件判断:
标准写法:
{{if age>18}}
年龄大于18
{{else if age<15}}
年龄小于15
{{else}}
年龄不符合要求
{{/if}}
原始写法:
<% if(age >18) { %>
年龄大于18
<% } else if(age<15>) { %>
年龄小于15
<% } else { %>
你不符合条件
<% } %>
5.循环
标准写法:
{{each target}}
{{$index}} {{$value}}
{{/each}}
原始语法:
<% for(var i=0;i<target.length;i++>) { %>
<%= i %> <%= target[i] %>
<% } %>
6.子模板(把网站公共部分抽离出来,进行引入)
标准语法: {{include '04.art' }}
原始语法: <%include('04.art') %>
7.模板继承:
1.使用{{block '名字'}} {{/block}} 设置插槽
2.使用{{extends './component/layout.art'}}
{{block '名字'}} 里面写内容 {{/block}}
8.模板配置
1.向模板中导入变量template.defaults.imports.变量名=变量值
2.模板默认后缀名temlate.defaults.
9.设置模板根目录
1.template.defaults.root=path.join(__dirname,'views');
2.直接使用文件路径
const html=template('02.art',{
time:new Date()
})
11.express框架的使用:
1.npm install express
引入express框架
const express=require('express')
2.创建网站服务器
const app=express()
3.创建路由
app.get('/',(req,res)=>{})
app.post('/list',(req,res)=>{})
4.监听端口
app.listen(3000)
express框架中的send()方法:
1.send方法内部会检测响应内容的类型,
2.send方法会自动设置http状态码
3.send方法会帮助我们自动设置响应的内容类型和编码
4.send方法可以返回一个json对象
12中间件:
12.1什么是中间件
中间件就是一堆方法,可以接收客户端的请求,可以对请求作出响应,也可以将请求继续交给下
一个中间件继续处理。
默认请求匹配到一个中间键的时候,是不会向下去继续匹配了,可以调用next()方法,允许请求向下执行。
app.get('/list',(req,res,next)=>{
//设置状态吗
res.status(200)
//继续匹配中间件
next()
})
12.2中间件
app.get()
app.post()
app.use() //get和post请求都可以
如果不传递路径,就是每个请求都会走这个中间件,但是必须调用next()方法继续执行后面的中间件。
app.use((req,res,next)=>{
next()
})
12.3中间件的应用:
1.用户访问登陆页面判断是否登陆
2.网站升级维护,用一个中间件直接响应网站在维护提示
3.自定义404页面
13.模块化路由:
const express=require('express')
const app=express()
//创建路由
const router=express.Router()
//将路由和请求路径进行匹配
app.use('/home',router)
router.get('/index',(req,res)=>{
res.send('welcome to index')
})
app.listen(3000)
14.1构建模块化路由
1.首先先新建文件,创建一个路由对象,
2.为路由对象匹配路径
3.module.imports=admin 导出路由对象
4.在app.js中引入路由对象,
5.在app.use中间件访问
15.express中接收get请求参数
调用req.query可以获取到请求参数
16.express中接受post请求参数
在express框架中,要获取到post参数需要使用body-parser模块
1.npm install body-parser
2.引入const bodyparse=require('body-parser')
3.拦截所有请求, app.use(bodyparse.urlencoded({extended:false}))
4.调用req.body获取参数
17 .路由参数
/add/:id 在添加路由的时候可以添加参数。id只是一个占位符具体传递的是值
可以使用req.params获取到参数值
18.静态资源方法
express.static方法可以设置静态资源访问。但是必须吧这个方法放到app.use中间件里面去
cosnt view=path.join(__dirname,'public')
app.use(express.static(view))
19.express中使用模板引擎 res.render('模板名字')
1.npm install art-template express art-template 下载
2. 当渲染后缀为art的模板时,使用express-art-template
app.engine('art',require('express-art-template'))
//设置模板存放目录
app.set('view',path.join(__dirname,'views'));
//渲染模板时不写后缀
app.set('view engine','art')
app.get('/list',(req,res)=>{
//渲染模板
res.render('index')
})
20.app.locals对象,
如果你需要在一些相同的模板中使用公共数据。可以把数据保存到app.locals这个对象里面。
app.locals.user=[{name:'xy',age:20}]
21.cookie和session
cookie存储在客户端,session存储在服务端,
每次请求都会携带cookie参数。
如何使用cookie和session保存用户登录成功的信息呢?
1.首先会用到一个第三方插件express-session,npm去下载它,
2.引用下载的插件,他会返回一个方法 const session=require('express-session')
3.使用一个中间件,调用执行这个方法,(配置session)
app.use(session({
secret:'secret key' //session进行加密
saveUninitialized: false, //不保留默认设置
cookie: {
maxAge: 24*60*60*1000 //设置cookie存储时间为1天
}
}))
4.用户登录成功,吧用户信息存储到session中,req.session.user=user.username
5.把用户信息存储到了客户端的cookie中,每次请求都会携带cookie。
22.express提供的跳转页面方法:
res.redirect('/admin/user')
23.如何把公共数据暴露到全局
将用户信息存储到local全局对象里面,
req.app.locals.userinfo=user
24.实现退出功能:
1.给退出按钮添加一个路由
2.创建一个退出登录的路由,
2.1删除session,如果删除成功调用回调函数
req.session.destroy(function()={
清除cookie,里面接收删除cookie的名字
res.clearCookie('connect.sid')
重定向到登录页面
res.redirect('/admin/login')
})
25.登录拦截:
1.在路由的前面添加一个中间件,
2. 排除login页面,并且用户未登录,就重定向到登录页面
3. 否则调用next()放行
26.使用form表单进行表单提交
第一步:如果form里面有二进制文件需要在form中声明一个属性:
enctype="multipart/form-data"
第二步:创建对应的表单提交路由,然后下载formidable并且引入
const formidable=require('formidable')
1.创建表单解析对象
const form=new formidable.IncomingForm();
2.设置文件上传路径
form.uploadDir="/my/dir"
3.是否保留表单上传文件的扩展名
form.keepExtensions=true (上传服务器的文件必须要保留扩展名)
4.form.parse(req,(err,fields,files)=>{
// err存储失败信息
// fields 存储普通请求参数
// files 存储上传的文件信息
})