Node.js02--07

路径操作模块path

  • path.basename
    • 获取一个路径的文件名(默认包含扩展名)
  • path.dirname
    • 获取一个路径的目录部分
  • path.extname
    • 获取一个路径的扩展名部分
  • path.parse
    • 把一个路径转换为对象
      • root根路径
      • dir目录
      • base包含后缀名的文件名
      • ext后缀名
      • name不包含后缀名的文件名
  • path.join
    • 当需要进行路径拼接的时候,就使用这个方法,这个方法可以纠正【拼接格式
  • path.isAbsolute
    • 判断一个路径是否是绝对路径

node中的非模块成员(其他成员)

在每个模块中除了require、exports等模块关键API之外,还有两个特殊成员:

  • _ dirname
    • 可以用来获取当前文件模块所属目录的绝对路径
    • 动态获取
  • _ filename
    • 可以用来获取文件的绝对路径
    • 动态获取
  • ./指的是相对于node命令所处的终端路径
    • 也就是说,文件操作路径中,相对路径设计指的是相对与node命令所处的终端路径
    • 在文件操作中,使用相对路径是不可靠的,所以为了解决这个路径,只需要把相对路径改成绝对路径就可以了
    • 所以可以使用_dirname_filename来解决这个问题了
    • _dirname_filename是不受node命令所属路径影响的
    • 在拼接路径的过程中,为了避免手动拼接带来的游戏额低级错误,所以推荐使用path.join()来辅助拼接。
    • 为了尽量避免路径带来的问题,我们以后再文件操作中使用的相对路径都统一转换为动态的绝对路径
  • 模块中的路径表示和这里的路径没有关系,不受影响(相对于文件模块),即用require引入模块的时候不能省略相对路径
    • 不受node命令所处路径影响
      1
      2
      3
      4
      5
      6
      7
      8
      9
      var fs = require('fs');
      fs.readFile(__dirname + '/a.txt','utf8',function(err,data){

      })

      //改进方法
      fs.readFile(path.join(__dirname,'/a.txt'),'utf8',function(err,data){

      })

知识点

  • date.now()会立即调用
  • date.now是一个方法
  • 表单具有默认的提交行为,默认是同步的,同步表单提交,浏览器会锁死等待服务器的响应结果。
  • 表单的同步提交以后,无论服务器响应的是什么,都会直接把响应的结果覆盖当前页面
  • 服务端重定向只针对同步请求有效,对异步请求无效

session

  • http是无状态的

  • cookie是 类似于小纸条,可以用来保存一些不太敏感的数据。但是不能用来保存用户登录状态

  • 可以用来保存一些其他信息:例如:记住用户名、购物车
    举例:

    1
    2
    3
    4
    5
    超市--》电子柜(服务端)--》你(客户端)(二维码小票(开箱凭证)cookie)(凭证是唯一的,不可能重复)
    一旦丢失,不可找回,如果小票丢失,你的状态也就丢失了。

    要是是服务器给的,所以就很安全了,不太容易伪造出来了。
    这个时候,我们就可以包一些敏感的数据来保存到服务端,客户端只需要拿着这把钥匙就可以了。
  • 在express这个框架中,默认不支持session和cookie

  • 所以需要第三方中间件:express-session

    • npm install express-session
    • 配置(一定要在app.use(router)之前)
    • 使用
      • 当把这个插件配置好以后,我们就可以通过req.session来访问和设置session成员
      • 添加session数据:req.seesion = ‘bar’
      • 访问session数据:req.session.foo

配置:

1
2
3
4
5
6
7
8
9
//该插件为req请求对象添加一个成员:req.session默认是一个对象
//这是最简单的配置方式,暂且先不用关心里面参数的含义
app.use(session({
//配置加密字符串,它会爱原有加密基础上和这个字符串拼接起来去加密
//目的是为了增加安全性,防止客户端恶意伪造
secret:'itcast',
resave:false,
saveUninitialized:false//无论是否使用session,我都能默认直接给你分配一把钥匙
}))

使用:

1
2
3
4
//添加session数据
req.session.foo = 'bar';
//获取session数据
req.session.foo

提示:默认session数据是内存存储的,服务器一旦重启就会丢失,真正的生产环境会把session持久化存储。

写案例步骤

目录结构:

  • app.js 项目的入口文件
  • controllers
  • models 存储使用mongoose设计的数据模型
  • node_modules 第三方包
  • package.json 包描述文件
  • package-lock.json 第三方包版本锁定文件(npm5以后才有)
  • public 公共的静态资源
  • README.md 项目说明文档
  • routes 如果业务比较多,代码量大,最好把路由按照业务的分类存储到routes目录中
  • router.js 简单一点把所有的路由都放到这个文件
  • views 存储视图目录

步骤:

  • 创建目录结构
  • 整合静态-模板页
    • include
    • block
    • extend
  • 设计用户登录、退出、注册的路由
  • 用户注册
    • 先处理好客户端页面的内容(表单控件的name、收集表单数据、发起请求)
    • 服务端
    • 先获取客户端请求数据
    • 操作数据库
      • 如果有错,发送500告诉客户端服务器报错
      • 其他根据业务发送不同的响应数据
  • 用户登录
  • 用户退出

总结

  • path模块
  • __ dirname 和__filename两个属性
    • 动态的,获取当前文件或者文件所处目录的绝对路径
    • 用来解决文件操作路径的相对路径问题
    • 因为在文件操作中,相对路径相对于执行node命令所处的目录
    • 所以为了尽量避免这个问题,都建议文件操作的目录都转为动态的
    • 方式:path.join(__ dirname,’文件名’)
  • art-template模板引擎高级语法
    • include
    • extend
    • block
  • 表单同步提交和异步提交
    • 以前没有ajax都是这么干的,甚至有些直接就是渲染了提示信息出来了
    • 异步提交页面不会刷新,交互方式更灵活
  • express中配置使用express-session中间件

表单同步和异步的区别

同步:提交请求-》等待服务器处理-》处理完毕返回 这个期间客户端浏览器不能干任何事
异步:请求通过事件触发-》服务器处理(这时浏览器仍然可以做其他事情)-》处理完毕

中间件

处理请求的,本质就是个函数。我们把用户从请求到响应的整个过程分发到多个中间件中去处理,这样做的目的是为了提高代码的灵活性,动态可扩展的。

在express中,对中间件有几种分类:

1、不关心请求路径和 请求方法的中间件,也就是说任何请求都会进入这个中间件

中间件本身是一个方法,该方法接收三个参数:request请求对象,response响应对象,next下一个中间件。next是一个方法会调用下一个中间件。

1
2
3
4
5
6
7
8
9
10
app.use(function(req,res,next){
console.log('1')
next()
})

app.use(function(req,res,next){
console.log('2')
next()
})
//1 2

添加next,就会调用下一个中间件,所以调用next也是要匹配的,不是调用紧挨着的。如果请求进入中间件后,如果没有next则代码会停在当前中间件,如果调用了next则往后找到匹配的下一个中间件

2、关心路径请求的中间件,以/xxx开头的路径中间件

1
2
3
4
app.use('/a',function(req,res,next){
console.log('1')
next()
})

没有匹配中间件express会默认输出 CAN NOT GET/

3、除了以上中间件之外,还有一种最尝试用的严格匹配请求方法和匹配请求路径的中间件

app.get,app.post

1
2
3
app.get('/a',function(req,res,next){

})

如果中间件没有next则不会往下执行,只会停留在当前中间件
当调用next的时候,如果传递了参数v,则直接往后找到带有这个参数应用程序级别中间件
当发生错误的时候,我们可以调用next传递错误对象,然后就会被全局错误处理中间件匹配到并处理之

-------------本文结束感谢您的阅读-------------