Node.js02--04

文件路径和模块路径关系

文件操作中的相对路径./可以省略,模块加载中的相对路径./不能省略

  • 使用的所有文件操作API都是异步的

修改完代码自动重启

使用一个第三方命令行工具,nodemon来帮助我们频繁修改代码重启服务器问题。
nodemon是一个居于node.js开发的一个第三方命令行工具,我们使用的时候需要独立安装

1
npm install --global nodemon//在任意目录执行该命令都可以

安装完毕之后,使用:

1
2
3
4
5
//以前使用方式
node app.js

//现在的方式
nodemon app.js

只要是通过nodemon app.js启动的服务,它就会监视你的文件变化,当文件发生变化的时候,自动帮助我们重启服务器。

express

基本路由

路由就是一张表,表里面由具体的映射关系。

  • 请求方法
  • 请求路径
  • 请求处理函数
    get:
    1
    2
    3
    4
    //当你以get方法请求/的时候,执行对应的处理函数
    app.get('/',function(req,res){
    res.send('hello express!!!')
    })

post:

1
2
3
4
//当你以post防范请求/的时候,指定对应的处理函数
app.post('/',function(req,res){
res.send('get a post request')
})

静态服务

当以’/public/‘开头的时候,去’./public’目录中查找相对应的文件,访问路径必须要添加/public/

1
2
// /public/xxx
app.use('/public/',express.static('./public'))

当省略第一个参数的时候,则可以通过省略/public的方式来进行访问,可以额访问路径不用添加/public/

1
2
// /xxx
app.use(express.static('./public'))

以下的方法代表的是以/static/来替换./public,也就是说,/static/是./public的别名

1
2
// /static/xxx
app.use('/static/',express.static('./public'))

在express中配置使用art-template模板引擎

安装:

1
2
npm install --save art-template
npm install --save express-art-template

配置使用art-template模板引擎,第一个参数表示当渲染以.art结尾的文件的时候,使用art-template模板引擎.
express-art-template是专门用来在express中把art-template整合到express中的,虽然这里不需要加载art-template,但是也必须安装该包,原因就在于express-art-template依赖了art-tempplate。

1
app.engine('art',require('express-art-template'))

express为response相应对象提供了一个方法:render。render方法默认是不可以使用,但是如果配置了模板引擎就可以使用了。
语法:

1
res.render('html模板名',{模板数据})

读取html模板名文件,渲染模板数据。第一个参数不能写路径,默认会去项目中的views目录中查找该模板文件,也就是说,express有一个约定:开发人员把所有的视图文件都放到views目录中。
例如:

1
2
3
4
5
6
7
8
app.get('/',function(req,res){
res.render('404.art')
})
/*
注意:
1res.render('404.art')不能写成res.render('./views/404.art'),因为会默认去views这个目录下面查找
2、要把views目录中对应的html文件名的后缀改成.art
*/

如果不想要把改变views目录中文件的后缀名(不想把.html改成.art)的话,就需要在加载引擎的时候重新定义,即把:
app.engine('art',require('express-art-template'))中的第一个参数由’art’改成’html’,这样的话加载的html文件就不需要改变后缀名了。

1
2
3
4
app.engine('art',require('express-art-template'))
app.get('/',function(req,res){
res.render('404.html')
})

如果想要修改默认的views目录。则可以使用set方法:

1
2
app.set('views',render函数的默认路径)
app.set('views','public')

总结

  • 安装

    • npm install --save art-template
    • npm install --save express-art-template
  • 配置

    • app.engine('art',require('express-art-template'))
    • 以上方法配置的时候,render的文件后缀名只能是.art
    • 如果向以.html为文件后缀名,需要把上述配置语句改为:
    • app.engine('html',require('express-art-template'))
  • 使用

    1
    2
    3
    4
    5
     app.get('/',function(req,res){
    res.render('index.html',{
    title:'hello world'
    })
    })
  • 如果希望修改默认的views视图渲染存储目录,可以:

    • app.set('views',render函数的默认路径)
    • 注意:第一个参数不能写错

在express中配置解析表单post请求体数据

当以POST请求/post的时候,执行指定的处理函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
app.post('/post'function(req,res){
//1. 获取表单POST请求体数据
//2.处理
//将数据保存到db.json文件中用以持久化
//3.发送响应
/*
因为文件中json存取的都是字符串,所以要先读取出来,转成对象
然后往对象中push数据
然后把对象转换为字符串
然后把字符串再次写入文件

//req.query只能获取get方法的数据

});

在express中没有内置获取表单POST请求体的API,这里我们需要一个第三方的包:body-parser

  • 安装
    • npm install –save body-parser
  • 配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var express = require('express')
    //0 引包
    var bodyParser = require('body-parser')
    var app = express()

    //配置
    //只要加入这个配置,则在req对象上会多出来一个属性:body
    //也就是说可以直接通过req.body来获取表单POST请求体数据了
    //parse app
    app.use(bodyParser.urlencoded({extended:false}))

    //parse app/json
    app.use(bodyParser.json())

    app.use(function(req,res){
    res.setHeader('Content-Type','text/plain')
    res.write('you posted:\n')
    res.end(JSON.stringify(req.body,null,2))
    })
    res.send,res.redirect这些方法会自动结束响应

配置中间件body-parser

配置模板引擎和body-parser一定要在app.use(router)挂载路由之前,中间件加载是从上到下

从文件中读取各种数据

模板引擎循环读取一些数据的时候,首先在app的

1
2
3
4
5
6
7
8
9
res.render('index.html'),{
students:[
{"name":"a","age":18,"gender":0,"hobbies":"singing,dancing"},
{"name":"b","age":18,"gender":0,"hobbies":"singing,dancing"},
{"name":"c","age":18,"gender":0,"hobbies":"singing,dancing"},
{"name":"d","age":18,"gender":0,"hobbies":"singing,dancing"},
{"name":"e","age":18,"gender":0,"hobbies":"singing,dancing"}
]
}

然后在index.html中这样写就可以了:

1
2
3
4
5
6
7
8
9
10
11
<tbody>
<!-- 模板引擎循环渲染写法格式如下 -->
{{ each fstudents }}
<tr>
<td>{{ $value.name }}</td>
<td>{{ $value.age }}</td>
<td>{{ $value.gender }}</td>
<td>{{ $value.hobbies }}</td>
</tr>
{{ /each }}
</tbody>

就可以了

从文件中读取到的数据一定是字符串,所以需要手动转换成对象,需要对象的形式来放在render的第二个参数对象之中。

1
2
3
4
5
6
7
8
9
fs.readFile('./db.json',function(err,data){
if(err){
return res.status(500).send('Server error')
}
/*console.log(data.toString()),因为data传过来是字符串,但是是二进制编码字符串,所以如果需要看清楚的话,需要加data.toString()来转换成我们能认识的字符串*/
res.render('index.html',{
students:JSON.parse(data).students//从文件中读取到的数据一定是字符串,所以需要手动转换成对象
})
})

注意:students:JSON.parse(data).students,一定要加.students这个对象属性,因为传过来得到的data是一个对象,对象包括了该文件里面的所有数据,所以不加.student的话,就找不到循环遍历的一些属性,students是data对象中的一个对象,必须要有这个关系存在才可以引用这个对象进行相关操作

小总结:

  • nodemon
  • express
    • art-template模板引擎配置(art-template、express-art-template)
    • body-parser解析表单POST请求体

CRUD

增删改查

新建项目步骤:
1、新建文件夹
2、cd 文件夹名字,进入文件夹
3、在该文件夹下npm init -y 进行初始化,会在该文件夹根目录下生成package.json文件
4、再在该文件夹中npm install –save express下载并生成express框架依赖
5、新建app.js文件、public文件夹和views文件夹
6、要想使用res.render方法进行渲染页面的话,必须要配置模板引擎

路由模块的提取

express提供了一种方式专门用来包装路由的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var fs = require('fs')
var express = require('express')

//1.创建一个路由容器
var router = express.Router()

//2.把路由都挂载到router路由容器中
router.get('/students/new',function(req,res){

})
router.post('/students/new',function(req,res){

})
router.get('/students/new',function(req,res){

})

//3.把router导出
module.exports = router

以上代码都是在router.js中写的,在app.js中没有

在app中的代码:

1
2
3
4
var router = require('./router')

//把路由容器挂载到app服务中
app.use(router)

app.js

  • 入门模块,职责:
    • 启动服务
    • 做一些服务相关配置
      • 模板引擎
      • body-parser 解析表单 post请求体
      • 提供静态资源的服务
    • 挂载路由
    • 监听端口启动服务

router.js

  • 路由模块,职责:
    • 处理路由
    • 根据不同的请求方法+请求路径设置具体函数

student.js

操作数据的API

  • 数据操作文件模块
    • 操作文件中的数据,只处理数据,不关心业务
      例如:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      //获取所有学生列表    return[]
      exports.find = function(){

      }

      //添加保存学生
      exports.save = function(){

      }

      //更新学生信息
      exports.update = function(){

      }

      //删除学生信息
      exports.delete = function(){

      }

自己编写的步骤

  • 处理模板
  • 配置开放静态资源
  • 配置模板引擎
  • 路由设计
  • 提取路由模块
  • 由于接下来的一系列操作都需要处理文件数据,所以需要处理业务数据文件
  • 业务文件结构
  • 实现具体功能
  • 业务功能顺序
  • 简单路由

回调函数

  • 如果需要获取一个函数中异步操作的结果,则必须通过回调函数来获取
  • 回调函数的目的就是为了获取异步操作的结果

不成立的情况:

1
2
3
4
5
6
7
8
9
10
11
12
function add(x,y){
consle.log(1)
setTimeout(function(){
console.log(2)
var ret = x + y
return ret
},0)
console.log(3)
//执行到这里就结束了,不会等到前面的定时器,所以就直接返回了undefined
}

console.log(add(10,20))//1,3,undefined,2
1
2
3
4
5
6
7
8
9
10
11
12
13
function add(x,y){
consle.log(1)
var ret
setTimeout(function(){
console.log(2)
ret = x + y
},0)
console.log(3)
return ret
//执行到这里就结束了,不会等到前面的定时器,所以就直接返回了undefined
}

console.log(add(10,20))//1,3,undefined,2

注意:凡是需要得到一个函数内部异步操作(setTimeout、readFile、writeFile、ajax,往往异步API都伴有一个回调函数:$.get(‘/‘,function(){}))的结果,这种情况必须通过回调函数取得。
回调函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function add(x,y,callback){

//callback就是回调函数
// var x = 10
//var y = 20
//var callback = function(ret){ console.log(ret) }

consle.log(1)
setTimeout(function(){
console.log(2)
var ret = x + y
callback(ret)
},0)
console.log(3)
}

add(10,20,function(ret){
console.log(ret)//1,3,2,30
//我现在得到这个函数可以做任何操作
})

基于原生XMLHttpRequest封装get方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function get(url,callback){
var o = new XMLRequest()
//当请求加载成功之后要调用指定的函数
o.onload = function () {
//我现在需要得到这里的o.responseText
callback(o.responseText)
}

o.open("get",url,true)
o.send()
}

get('data.json',function (data){
console.log(data)
})
-------------本文结束感谢您的阅读-------------