Express的请求方式——get、post、patch、delete

3,002 阅读5分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

提到node就会想到express,刚开始在学习express还是有点艰难的,在b站找了很多课程看,从基础一步一步学起。

Express

一、介绍Express

Express有丰富的基础API支持,以及常见的HTTP辅助程序,例如重定向、缓存等;有强大的路由功能、灵活的中间件;高性能且稳定;Express仅仅提供了web开发的基础功能,它通过中间件的方法集成了许多外部插件来处理HTTP请求。

  • body-parser:解析HTTP请求体
  • compression:压缩HTTP响应
  • cookie-parser:解析cookie数据
  • cors:处理跨域资源请求
  • morganHTTP请求日志记录
  • ...

Express的中间件让Express本身变得更加灵活和简单,而缺点在于虽然有一些中间件包跨域解决几乎所有问题或需求,但是挑选合适的包有时也会成为一个挑战。Express不对Node.js已有的特性进行二次抽象,只是在它之上扩展了web应用所需要的基本功能;

  • 内部使用的还是HTTP模块
  • 请求对象继承自:http.IncomingMessage
  • 响应对象继承自:http.ServerResponse

有很多流行框架基于Express,比如LoopBackSailsNextJs

Express的Hello World

引入express模块,创建一个服务器,再对浏览器的get请求做出响应;

const express = require('express');
const app = express();
app.get('/', (req, res) => {
    res.send('Hello World!');  // 发送响应
})
app.listen(3000);

二、路由基础

路由是指确定应用程序如何响应客户端对特定端点的请求,该特定端点是URI(或路径)和特定的HTTP请求方法(get,post等)。每个路由可以具有一个或多个处理程序函数,这些函数在匹配该路由时执行;采用下面的结构来实现:(如上面的get请求)

app.method(path, handle); 
  • app是Express实例
  • method是小写的HTTP请求方法
  • path是服务器上的路径
  • handle是当路由匹配执行的功能

请求和响应

Express应用使用路由回调函数的参数:requestresponse对象来处理对应的请求和响应的数据;

  • 请求对象:获取请求相关的信息;继承自http.IncomingMessage

  • 在express中可以通过req.query获取请求参数 ;具体参考Express - API文档

  • 响应对象:用来处理请求发送响应;继承自http.ServerResponse

    res.cookie('foo', 'bar');
    res.status(201).send({foo: 'bar'});    // 设置状态并响应
    

三、四种请求方式

我们在写每一个路由的时候,一般都要读取一些内容后对浏览器进行响应,比如说我们把数据放在db.json文件里面,然后再app.js文件中用fs.readFile()读取数据;这里可以把app.js中使用的一些使用频率高的方法写在另一个文件db.js里面,比如fs.readFiles()方法;

const fs = require('fs')
const { promisify } = require('util')
const path = require('path');
const readFile = promisify(fs.readFile);
const dbPath = path.join(__dirname, './db.json');  // 绝对路径
exports.getDb = async () => {
    const data = await readFile(dbPath, 'utf-8');
    return JSON.parse(data);
}

1. get请求

封装完之后在app.js中通过await getDb()就可以获取到对应的数据内容了;(记得async);如果不存在的话就返回404状态码,如果找到了就响应所找到的数据内容;用try...catch是为了避免一小部分错误导致整个程序无法运行;注意:req.params为请求参数

const { getDb } = require('./db')
app.get('/todos/:id', async (req, res) => {
    try {
        const db = await getDb();
        const todo = db.todos.find(todo => todo.id === Number.parseInt(req.params.id));
        if (!todo) { return res.status(404).end(); }
        res.status(200).json(todo);
    } catch (err) {
        res.status(500).json({
            error: err.message
        })
    }
})

2. post请求

  • 配置解析表单请求体

    application/jsonapp.use(express.json());将json形式的数据转为js对象;

    application/x-www-form-urlencodedapp.use(express.urlencoded)

  • post我们一般用来提交数据,这里的话就要用到fs.writeFile

  • 同样地,把方法写在db.js文件中;在写入数据的时候,我们如果想要让json中的数据看起来是有格式的话,以(db, null, ' ')为参数即可;

    exports.saveDb = async () => {
        const data = JSON.stringify(db, null, '  ');  // 让db.json中的数据有格式
        await writeFile(dbPath, data);
    }
    
  • 随后在app.js对数据进行处理,如果todo.title不存在的话就返回404,如果存在的话就将添加的数据push到对应的数组(todo)中,数据提交后对数据进行写入处理;

    try {
        if (!todo.title) {
            return res.status(404).json({ error: 'The field title is required' })
        }
        const db = await getDb();
        const lastTodo = db.todos[db.todos.length - 1];
        todo.id = lastTodo ? lastTodo.id + 1 : 1;
        db.todos.push(todo);
        await saveDb(db);
        res.status(200).json(todo);
    } catch (err) {
        res.status(500).json({
            error: err.message
        })
    }
    

3. patch请求

  • 首先要通过req.body获取表单数据:const todo = req.body;

  • 查找要修改的任务项,如果没有找到就说明不用改了,直接返回404即可;如果找到了就对这个数据进行修改,

    const db = await getDb();
    const ret = db.todos.find(todo => todo.id === Number.parseInt(req.params.id));
    if (!res) {
        return res.status(404).end();
    }
    Object.assign(ret, todo);
    await saveDb(db);
    res.status(200).json(ret);
    

    注意:Object.assign方法是浅拷贝,第一个参数是目标对象,后面的参数都是源对象;如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性;

4. delete操作

  • 找到要删除的项

    const todoId = Number.parseInt(req.params.id);
    const db = await getDb();
    const index = db.todos.findIndex(todo => todo.id === todoId);
    
  • findIndex这个API查找返回索引,如果没找到就返回-1;找到后删除这个数据即可;

    if (index === -1) { return res.status(404).end(); }
    db.todos.splice(index, 1);
    await saveDb(db);
    res.status(200).end();
    

一直都挺好奇浏览器和服务器之间是怎么进行连接的,终于学到express了解到这个过程了