Node.js学习笔记

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 生成。
Node.js学习笔记_第1张图片
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)})

Express框架的使用

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 存储上传的文件信息
})

你可能感兴趣的:(Node.js)