4、后台项目的开发

2022-06-18 08:26:26 浏览数 (2)

4、后台项目的开发

1.后台项目的目标

我们已经学习完了 KOA2 的快速上手, 并且对 KOA2 当中的中间件的特点页进行了讲解. 接下来就是利用KOA2 的知识来进行后台项目的开发,后台项目需要达到这以下几个目标:

1.计算服务器处理请求的总耗时

计算出服务器对于这个请求它的所有中间件总耗时时长究竟是,我们需要计算一下

2.在响应头上加上响应内容的 mime 类型

加入mime类型, 可以让浏览器更好的来处理由服务器返回的数据.

如果响应给前端浏览器是 json 格式的数据,这时候就需要在咱们的响应头当中增加 Content- Type 它的值就是 application/json , application/json 就是 json 数据类型的 mime 类型

3.根据URL读取指定目录下的文件内容

为了简化后台服务器的代码,前端图表所要的数据, 并没有存在数据库当中,而是将存在文件当中的,这种操作只是为了简化咱们后台的代码. 所以咱们是需要去读取某一个目录下面的文件内容的。

每一个目标就是一个中间件需要实现的功能, 所以后台项目中需要有三个中间件

2.后台项目的开发步骤

创建一个新的文件夹, 叫做 koa_server , 这个文件夹就是后台项目的文件夹

1.项目准备

1.安装包

npm init -y

npm install koa

2.创建文件和目录结构

app.js 是后台服务器的入口文件

data 目录是用来存放所有模块的 json 文件数据

middleware 是用来存放所有的中间件代码

koa_response_data.js 是业务逻辑中间件

koa_response_duration.js 是计算服务器处理时长的中间件

koa_response_header.js 是用来专门设置响应头的中间件

接着将各个模块的 json 数据文件复制到 data 的目录之下, 接着在 app.js 文件中写上代码如下:

代码语言:javascript复制
// 服务器的入口文件 
// 1.创建KOA的实例对象 
const Koa = require('koa') 
const app = new Koa() 
// 2.绑定中间件 
// 绑定第一层中间件 
// 绑定第二层中间件 
// 绑定第三层中间件 
// 3.绑定端口号 8888 
app.listen(8888)

2.总耗时中间件

1.第1层中间件

总耗时中间件的功能就是计算出服务器所有中间件的总耗时,应该位于第一层,因为第一层的中间件是最先处理请求的中间件,同时也是最后处理请求的中间件

2.计算执行时间

第一次进入咱们中间件的时候,就记录一个开始的时间

当其他所有中间件都执行完之后,再记录下结束时间以后

将两者相减就得出总耗时

3.设置响应头

将计算出来的结果,设置到响应头的 X-Response-Time 中, 单位是毫秒 ms

具体代码如下:

app.js

// 绑定第一层中间件

代码语言:javascript复制
const respDurationMiddleware = require('./middleware/koa_response_duration') 
app.use(respDurationMiddleware)

koa_response_duration.js

代码语言:javascript复制
// 计算服务器消耗时长的中间件 
module.exports = async (ctx, next) => {
  // 记录开始时间
  const start = Date.now() 
  // 让内层中间件得到执行 
  await next() 
  // 记录结束的时间 
  const end = Date.now() 
  // 设置响应头 X-Response-Time 
  const duration = end - start 
  // ctx.set 设置响应头 
  ctx.set('X-Response-Time', duration   'ms') 
}

3.响应头中间件

1.第2层中间件

这个第2层中间件没有特定的要求

2.获取 mime 类型

由于咱们所响应给前端浏览器当中的数据都是 json 格式的字符串,所以 mime 类型可以统一的给它写成 application/json , 当然这一块也是简化的处理了,因为 mime 类型有几十几百种,我们我们没有必要在我们的项目当中考虑那么多,所以这里简化处理一下

3.设置响应头

响应头的key是 Content-Type ,它的值是 application/json , 顺便加上 charset=utf-8

告诉浏览器,我这部分响应的数据,它的类型是 application/json ,同时它的编码是 utf- 8

具体代码如下:

app.js

// 绑定第二层中间件

代码语言:javascript复制
const respHeaderMiddleware = require('./middleware/koa_response_header') 
app.use(respHeaderMiddleware)

koa_response_header.js

// 设置响应头的中间件

代码语言:javascript复制
module.exports = async (ctx, next) => { 
    const contentType = 'application/json; charset=utf-8' 
    ctx.set('Content-Type', contentType) 
    await next() 
}

4.业务逻辑中间件

1.第3层中间件

这个第3层中间件没有特定的要求

2.读取文件内容

获取 URL 请求路径

const url = ctx.request.url

1

根据URL请求路径,拼接出文件的绝对路径

代码语言:javascript复制
let filePath = url.replace('/api', '') 
filePath = '../data'   filePath   '.json'
filePath = path.join(__dirname, filePath)

这个 filePath 就是需要读取文件的绝对路径

读取这个文件的内容

使用 fs 模块中的 readFile 方法进行实现

3.设置响应体

ctx.response.body

具体代码如下:

app.js

// 绑定第三层中间件

代码语言:javascript复制
const respDataMiddleware = require('./middleware/koa_response_data') 
app.use(respDataMiddleware)

koa_response_data.js

// 处理业务逻辑的中间件,读取某个json文件的数据

代码语言:javascript复制
const path = require('path') 
const fileUtils = require('../utils/file_utils') 
module.exports = async (ctx, next) => { 
    // 根据url 
    const url = ctx.request.url // /api/seller ../data/seller.json 
    let filePath = url.replace('/api', '') // /seller 
    filePath = '../data'   filePath   '.json' // ../data/seller.json 
    filePath = path.join(__dirname, filePath) 
    try { 
        const ret = await fileUtils.getFileJsonData(filePath) 
        ctx.response.body = ret
    } catch (error) { 
        const errorMsg = { 
            message: '读取文件内容失败, 文件资源不存在', 
            status: 404 
        }
        ctx.response.body = JSON.stringify(errorMsg) 
    }
    console.log(filePath) 
    await next() 
}

file_utils.js

// 读取文件的工具方法

代码语言:javascript复制
const fs = require('fs') 
module.exports.getFileJsonData = (filePath) => { 
    // 根据文件的路径, 读取文件的内容 
    return new Promise((resolve, reject) => { 
        fs.readFile(filePath, 'utf-8', (error, data) => { 
            if(error) { 
                // 读取文件失败 
                reject(error) 
            } else { 
                // 读取文件成功 
                resolve(data) 
            } 
        }) 
    }) 
}

5.允许跨域

设置响应头

代码语言:javascript复制
app.use(async (ctx, next) => { 
    ctx.set("Access-Control-Allow-Origin", "*") 
    ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE") 
    await next(); 
})

0 人点赞