Node03


小概

本章学习的是Express框架的使用,它是一个基于Node.js的第三方框架,可以更快 更好用的开发web应用。


1. express框架的使用

在项目文件夹目录下 npm init 初始化项目
使用 npm i express 将这个模块下载到本地
使用文档地址:http://expressjs.com/(官方文档) http://expressjs.com.cn/(中文文档)

创建一个简单的服务端

//1. 导入express模块
const express = require('express');

//2.  创建应用
const app = express();

//3. 注册路由
//   就是规定前端的URL和请求方法对应的处理逻辑.
app.get('/index', (req, res) => {
    res.send('你好,Express!');
});
//这个回调函数,是用来处理http请求的
//处理哪一个?
//请求方式是get并且URL是  /index

//4. 开启监听.
app.listen(80, () => console.log('服务启动成功!'));

2. express路由注册

//1. 导入express模块
const express = require('express');

//2.  创建应用
const app = express();

//3. 注册路由
//   就是规定前端的URL和请求方法对应的处理逻辑.
//   只能接收get请求,并且url要和第1个参数匹配.
app.get('/index', (req, res) => {
    res.send('你好,Express!');
});
//这个回调函数,是用来处理http请求的
//处理哪一个?
//请求方式是get并且URL是  /index

//  只接收post请求,并且url要和第1个参数匹配.
app.post('/addStudent', (req, res) => {
    res.send('接收post请求');
});

//注册路由 路由匹配
//请求方式只能是delete
//url要和第1个参数匹配.
app.delete('/student', (req, res) => {
    res.send('ok');
});

//4. 开启监听.
app.listen(80, () => console.log('服务启动成功!'));

express的路由匹配与原生的node.js路由匹配的区别
express可以为符合条件的http请求精准匹配处理逻辑(app.get只接收get请求,并且url必须要和第1个参数完全匹配.;app.post只接收post请求,并且url必须要和第1个参数完全匹配)
而原生则需要大量的if else来判断req.url和req.method
express已经对url的大小写做了兼容处理;如果服务端没有与路由匹配的处理逻辑,那么它会自动的返回404响应状态码
Node.js中res.end():1.结束本次响应.向响应体中追加数据,2.参数只接收string Buffer ,3.在处理完请求之后,必须要调用1次,最多只能调用1次.
express中res.send():1.结束本次响应,
2.向响应体中追加数据
string
Buffer
array -> json(自动转成json类型)
object -> json(自动转成json类型)

3.在处理完请求之后,必须要调用1次,最多只能调用1次.
4. 自动根据返回的内容设置Content-Type, 并且还会自动的设置字符编码
原生node需要获取请求ip需要自己写函数调用,express可以直接通过req.ip得到请求ip地址

关于http的请求方式

  1. GET: 从服务端获取数据.
  2. POST: 新增数据.
  3. PUT/PATCH: 数据/资源的修改.
  4. DELETE: 删除资源/数据

3. express的五个对象

1.express对象
2.Application对象 (就是我们创建出来的app。)
3.Request对象 (回调函数的第1个参数 req)
4.Response对象 (回调函数的第2个参数 res)
5.Router对象 (路由)

4. express路由匹配

普通路由注册(请求方法和URL都需要完全匹配.)
app.get
app.post
app.put
app.delete

app.use();

  1. 不限定http请求方法.
  2. URL只需要第1部分匹配就行.
  3. 如果第1个参数省略,那么第1个参数的默认值就是 /

app.all();

  1. 不限定请求方式
  2. url必须要和第1个参数完全匹配.

5. express静态资源托管(静态资源服务器)

const express = require('express');
const path = require('path');
const app = express();

//1. 将public目录下的文件做静态资源托管.
app.use(express.static(path.join(__dirname, 'public')));

//不限制请求方式.
//第1个参数省略掉.   '/'
//第2个参数是1个 req res 的回调.
//express.static的返回值 就是1个 req res的回调函数.
app.use(); //可以托管多个文件

app.listen(80, ()=>console.log('服务启动成功'));

app.use()第一个参数可以省略 默认就是/ ,express.static()的返回值就是一个req res的回调函数,static翻译过来就是静态的(adj)的意思。

6. 获取joke案例

API: /api/joke
method: get
返回:{
code: 处理状态码
count: 服务器一共有多少条笑话
joke: 随机的一条笑话内容
}

const express = require('express');
const app = express();

app.get('/api/joke', (req, res) => {
    //随机的返回一条笑话的内容.

    //1. 将jokes.json文件读取出来.
    //   如果我们要读取一个json文件,并且这个json文件中的内容是一个标准的json字符串.
    //   可以直接使用 require函数加载.
    const jokes = require('./data/jokes.json');

    //2. 产生1个随机的下标.
    const randomIndex = Math.floor(Math.random() * jokes.length);

    //3. 返回数据
    //   设置http的响应状态码
    res.status(200).send({
        code: 200,
        count: jokes.length,
        joke: jokes[randomIndex]
    });
})

原生node.js设置响应状态码是res.statusCode = 状态码,express是res.satus(200).send({})实现链式编程
如果要获取一个json文件,而且json文件中的内容是一个标准的json字符串,可以直接用require(‘文件地址’)得到一个js类型的数据(之前我们是用node的内置模块fs和path来拿文件)

7. express获取get请求参数

express模块获得客户端get请求时,发过来的参数(req.query)
get请求是在url地址拼接传参的:http://127.0.0.1/joke?num=10&age=10
experss中提供了一个req.query可以直接拿到后面的参数(以对象键值对的形式拿到){num:10,age:10}

const express = require('express');
const app = express();


//       /index?name=jack&age=10
app.get('/index', (req, res) => {

    //拿客户端请求服务端的时候,发过来的数据.
    //console.log(req.query);

    const {name, age} = req.query;  //ES6解构赋值
    console.log(req.query);

    console.log(name, age);


    res.send('ok');
});
app.listen(80, ()=>console.log('服务启动成功'));

express获得get请求方式的参数:req.query (得到一个对象)

8. 案例2

需求:
API: /api/joke
Method: get
参数: page: 需要第几页的笑话
size: 每一页有多少条笑话数据.
返回: {
code: 处理状态码
count: 总共有多少条笑话.
size: 每一页的笑话数量
page: 当前是第几页.
jokes: [
…笑话数据
]}

const express = require('express');
const app = express();


app.get('/api/joke', (req, res) => {
    //1. 获取客户端通过URL传递过来的参数
    const { page, size } = req.query;
    //2. 判断参数有没有传递.
    if ((!page) || (!size)) return res.status(400).send({ code: 400, msg: '参数错误' });
    //3. 加载笑话库. 取到笑话库中的第page页的数据.
    //3.1 加载笑话库
    const jokes = require('./data/myjokes.json'); // 8880
    //3.2 size代表每一页有多少条数据, page代表要去取第几页的数据.
    //    size = 10    page = 3
    //    起始下标    结束下标. 找规律: 将现象摆出来,分析 观察
    //    第1页的数据   0      9
    //    第2也的数据  10     19
    //    第3页的数据  20     29
    //    第page页的数据  (page-1)*10     (page-1)*10+(10-1)
    //                   (page-1)*size   (page-1)*size + (size-1)

    //判断传递的页码是否超出了范围.
    //计算1下,笑话库的数据一共有多少页.

    //笑话库一共有多少页数据.
    const pageCount =  Math.ceil(jokes.length / size);   // 17/5 3.xxx
    //判断传递的页码是否在范围之内.
    if(page > pageCount) return res.status(400).send({code: 400, msg: '页码超出范围'});
    //如果请求的是最后一页,
    //结束的下标应该是: 数组的最后一个元素的下标.
    
    const startIndex = (page - 1) * size;
    let endIndex = startIndex + (size - 1)
    if(page == pageCount){ //请求页码是最后一页
        endIndex = jokes.length - 1;
    }

    const returnJokes = [];
    for (let i = startIndex; i <= endIndex; i++) {
        returnJokes.push(jokes[i]);
    }
    //3.3 返回数据
    res.send({
        code: 200,
        count: jokes.length,
        page,
        size,
        jokes: returnJokes
    });
});

app.listen(80, () => console.log('服务启动成功'));

除了上述的循环push数据到空数组里面,还可以用数组的slice截取,因为已经知道了开始下标和结束下标 可以直接returnJokes =[ … jokes.slice(startIndex ,endIndex +1)].
slice(开始截取下标(包含),结束下标(不包含)),返回一个新的数组。

9. express获取post请求参数

express模块获取post请求携带的参数

  1. 注册中间件 app.use(express.urlencoded({extended: false}));
  2. req.body
/*
  1. 如何接收浏览器通过post发送到服务器的数据.    
     req.body;

   2. 如果我们要去处理浏览器通过post发送到服务器的数据.
      必须要先注册1个中间件.
*/
const express = require('express');
const app = express();

//注册中间件, 只有注册了这个中间件.
//才可以通过req.body取到客户端通过post传到服务器的数据.
app.use(express.urlencoded({extended: false}));
app.post('/test', (req, res) => {
    console.log(req.body);
    res.send('ok');
});
app.listen(80, ()=>console.log('服务启动成功'));

10 案例3

post 请求新增一个笑话
需求: url: /api/joke/add
method post
参数: joke: 要新增的笑话.
返回{
code:
msg: ‘消息提示’
}

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();


app.use(express.urlencoded({ extended: false }));

//新增笑话的接口.
app.post('/api/joke/add', (req, res) => {
    //1. 获取浏览器传递到服务器的数据。
    const { joke } = req.body;
    //2. 判断客户端是否传递了这个参数
    if (!joke) return res.status(400).send({ code: 400, msg: '参数错误' });
    //3. 客户端有传递joke
    //   将笑话增加到笑话库中.
    //3.1 先将笑话库读取出来
    const jokes = require('./data/myjokes.json');
    //3.2 将笑话新增到
    // 新增的笑话对象的id:  是笑话库中最后1个笑话对象的id+1
    jokes.push({
        id: jokes[jokes.length-1].id + 1,
        content: joke
    });
    //3.3 写回
    fs.writeFile(path.join(__dirname, 'data/myjokes.json'), JSON.stringify(jokes), 'utf-8', err=>{
        if(err) return res.status(500).send({ code: 500, msg: '服务器内部发生错误' });
        //写入成功
        res.status(201).send({
            code: 201,
            msg: '创建成功'
        })
    });
});

app.listen(80, () => console.log('服务启动成功'));

总结

express路由注册:app.get (),app.post(),app.delete(),app.put() … 两个参数,第一个url,第二个(req,res){}回调函数
特殊的路由:app.use()第一个参数可以省略(/)这个是可以是任何方式的请求方式都能匹配,第一个参数只需要部分匹配就可以。
用来实现静态资源托管:app.use(express.static(path.join(__dirname, ‘public’)));
app.all():第一个参数url必须完全匹配,请求方式可以是任意。
express的五个对象:express,application,request,response,router
express获得get请求参数:req.query ;获得post请求参数:req.body(必须先注册中间件app.use(express.urlencoded({extened:false})) )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值