KOA2—后台项目的开发学习【第四日学习笔记】

一、后台项目的目标

后台项目将为前端图表提供各样的数据
我们已经学习完了 KOA2 的快速上手, 并且对 KOA2 当中的中间件的特点页进行了讲解. 接下来就是利用KOA2 的知识来进行后台项目的开发,后台项目需要达到这以下几个目标:
1.计算服务器处理请求的总耗时:计算出服务器对于这个请求它的所有中间件总耗时时长究竟是多少,我们需要计算一下。
2.在响应头上加上响应内容的 mime 类型:加入mime类型, 可以让浏览器更好的来处理由服务器返回的数据。
如果响应给前端浏览器是 json 格式的数据,这时候就需要在咱们的响应头当中增加 Content-Type 它的值就是 application/jsonapplication/json 就是 json 数据类型的 mime 类型
3.根据URL读取指定目录下的文件内容
为了简化后台服务器的代码,前端图表所要的数据, 并没有存在数据库当中,而是将存在文件当中的,这种操作只是为了简化后台的代码 所以需要去读取某一个目录下面的文件内容的。

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

二、后台项目的开发步骤

创建一个新的文件夹, 叫做 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 文件中写上代码如下:

// 服务器的入口文件
// 1.创建KOA的实例对象
const Koa = require('koa')
const app = new Koa()
// 2.绑定中间件
// 绑定第一层中间件(下文补充1)
// 绑定第二层中间件(下文补充2)
// 绑定第三层中间件(下文补充3)
// 3.绑定端口号 8888
app.listen(8888)

2.总耗时中间件

1)第1层中间件

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

2)计算执行时间

第一次进入咱们中间件的时候,就记录一个开始的时间当其他所有中间件都执行完之后,再记录下结束时间以后将两者相减就得出总耗时

3)设置响应头

将计算出来的结果,设置到响应头的 X-Response-Time 中, 单位是毫秒 ms
具体代码如下:

在app.js文件中

// 绑定第一层中间件(补充1)
const respDurationMiddleware =
 require('./middleware/koa_response_duration')
app.use(respDurationMiddleware)

在koa_response_duration.js文件中

// 计算服务器消耗时长的中间件
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')
}
以上是部分代码,现在将该模块代码拼接起来,如下:

在app.js文件中

//构造函数构造koa
const Koa = require('koa')
//创建koa实例对象
const app = new Koa()

//绑定中间件
//第一层中间件
/*1.计算执行时间
* 进入时开始记录,其他所有中间件执行完后记录结束时间,两者做差
* 2.设置响应头
* X-Response-Time:5ms*/

//require可将另一文件中导出的函数进行使用
const respDurationMiddleware = require('./middleware/koa_response_duration')//给得到的函数起名称
app.use(respDurationMiddleware)//将第一层中间件使用,将respDurationMiddleware放在括号中即可
//绑定端口号
app.listen(8888)

在koa_response_duration.js文件中

//中间件的本质是一个函数,该函数要应用在app.use()中去
//module.exports可以导出中间件函数
module.exports = async (ctx,next) =>{
    //ctx:上下文;next:内层中间件执行的入口

    //记录开始时间
    const start = Date.now()
    //让内层中间件得到执行
    await next()//await必须有async进行修饰,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 , 简化处理

3)设置响应头

响应头的key是 Content-Type ,它的值是 application/json , 加 charset=utf-8告诉浏览器,这部分响应的数据类型是 application/json ,同时它的编码是 utf-8

具体代码如下:
在app.js文件中

// 绑定第二层中间件(补充2)
const respHeaderMiddleware = require('./middleware/koa_response_header')
app.use(respHeaderMiddleware)

在koa_response_header.js文件中

// 设置响应头的中间件
module.exports = async (ctx, next) => {
	const contentType = 'application/json; charset=utf-8'
	ctx.set('Content-Type', contentType)
	await next()
}
以上是部分代码,现在将该模块代码拼接起来,如下:

在app.js文件中

//构造函数构造koa
const Koa = require('koa')
//创建koa实例对象
const app = new Koa()

//绑定中间件
//第一层中间件

/*1.计算执行时间
* 进入时开始记录,其他所有中间件执行完后记录结束时间,两者做差
* 2.设置响应头
* X-Response-Time:5ms*/

//require可将另一文件中导出的函数进行使用
const respDurationMiddleware = require('./middleware/koa_response_duration')//给得到的函数起名称
app.use(respDurationMiddleware)//将第一层中间件使用,将respDurationMiddleware放在括号中即可

//第二层中间件
const respHeaderMiddleware = require('./middleware/koa_response_header')
app.use(respHeaderMiddleware)
//绑定端口号
app.listen(8888)

在koa_response_header.js文件中

//设置响应头中间件
module.exports = async (ctx,next) => {
    const contentType = 'application/json; charset=utf-8'//??
    //通过ctx.set()设置响应头
    ctx.set('Content-Type', contentType)//??
    //展示效果:设置json格式的字符串
    ctx.response.body = '{"success": true}'

    //为使中间件得到执行需调用next()函数
    await next()
}

运行结果:
请添加图片描述
请添加图片描述

4.业务逻辑中间件

1)第3层中间件

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

2)读取文件内容

在koa_response_data文件中
①获取 URL 请求路径const url = ctx.request.url:获取浏览器发起请求的请求路径:返回处于端口之后的路径:/api/seller
②根据URL请求路径,拼接出文件的绝对路径

let filePath = url.replace('/api', '')
filePath = '../data' + filePath + '.json'
filePath = path.join(__dirname, filePath)

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

总体代码实现:

const path = require('path')//获得可访问的绝对路径
const fileUtils = require('../utils/file_utils')//与utils文件建立联系
module.exports = async (ctx, next) => {
    //功能:读取文件中的内容——根据请求的url进行读取
    const url = ctx.request.url//获取浏览器发起请求的请求路径:返回处于端口之后的路径:/api/seller
    //由浏览器的请求路径得到后台的文件路径:../data/seller.json
    let filePath = url.replace('/api', '')//将/api/seller替换为/seller
    filePath = '../data' + filePath + '.json' //将两个路径拼接在一起,得到后台的文件路径:../data/seller.json
    //__dirname:当前文件所处路径
    filePath = path.join(__dirname, filePath)//最后进行一次拼接获得可以被访问的路径
    const ret = fileUtils.getFileJsonData(filePath)//与utils文件建立联系
    ctx.response.body = ret
    console.log(filePath)//打印filePath
   await next()//调用next函数,确保内层中间件得以执行
}

③根据上一部分koa_response_data返回的绝对路径,读取后台文件中的内容
对外导出自定义函数getFileJsonData的函数,将文件的绝对路径filePath作为参数传入
总体代码实现:
在file_utils文件中

module.exports.getFileJsonData = (filePath) => {
    return 'haha'
}

运行结果:
请添加图片描述
④优化:不返回’haha‘而返回函数体
读取这个文件的内容,使用 fs 模块中的 readFile 方法进行实现
具体代码实现如下:
在file_utils文件中

//根据koa_response_data返回的绝对路径,读取后台文件中的内容
//对外导出getFileJsonData的函数,将文件的绝对路径filePath作为参数传入
const fs = require('fs')//获取fs模块
module.exports.getFileJsonData = (filePath) => {
    //根据文件路径,读取文件内容,需要使用fs模块
    return new Promise((resolve,reject) => {
        //参数1:文件路径;参数2:文件所需读取编码;参数3:读取文件成功or失败的回表函数
        fs.readFile(filePath, 'utf-8', (error, data) => {
        //读取文件失败时对error赋值,读取文件成功后对data参数进行赋值
            if (error){
                //读取文件失败
                reject(error)
            }
            else {
                //读取文件成功
                //注意这里使用函数return返回给readFile()函数的调用者,而不是getFileJsonData
                //对异步任务处理:包装在promise对象中
                //将读取成功后的数据传递到参数resolve中去
                resolve(data)
            }
        })
    })
}

在koa_response_data文件中
注意:获取成功之后函数返回的对象:await

const path = require('path')//获得可访问的绝对路径
const fileUtils = require('../utils/file_utils')//与utils文件建立联系
module.exports = async (ctx, next) => {
    //功能:读取文件中的内容——根据请求的url进行读取
    const url = ctx.request.url//获取浏览器发起请求的请求路径:返回处于端口之后的路径:/api/seller
    //由浏览器的请求路径得到后台的文件路径:../data/seller.json
    let filePath = url.replace('/api', '')//将/api/seller替换为/seller
    filePath = '../data' + filePath + '.json' //将两个路径拼接在一起,得到后台的文件路径:../data/seller.json
    //__dirname:当前文件所处路径
    filePath = path.join(__dirname, filePath)//最后进行一次拼接获得可以被访问的路径
    const ret = await fileUtils.getFileJsonData(filePath)//与utils文件建立联系
    //获取成功之后函数返回的对象:await
    ctx.response.body = ret
    console.log(filePath)//打印filePath
   await next()//调用next函数,确保内层中间件得以执行
}

运行结果:
请添加图片描述
换个地址试试:
请添加图片描述
解决非正确地址报错问题:
请添加图片描述
加入:

    try{
        //成功后响应头设置
        const ret = await fileUtils.getFileJsonData(filePath)//与utils文件建立联系
        //获取成功之后函数返回的对象:await
        ctx.response.body = ret
    } catch (error) {
        const errorMsg = {
            message:'读取文件内容失败,文件不存在!',
            status: 404
        }
        //errorMsg对象所形成的json格式的字符串
        ctx.response.body = JSON.stringify(errorMsg)
    }

具体代码实现:

const path = require('path')//获得可访问的绝对路径
const fileUtils = require('../utils/file_utils')//与utils文件建立联系
module.exports = async (ctx, next) => {
    //功能:读取文件中的内容——根据请求的url进行读取
    const url = ctx.request.url//获取浏览器发起请求的请求路径:返回处于端口之后的路径:/api/seller
    //由浏览器的请求路径得到后台的文件路径:../data/seller.json
    let filePath = url.replace('/api', '')//将/api/seller替换为/seller
    filePath = '../data' + filePath + '.json' //将两个路径拼接在一起,得到后台的文件路径:../data/seller.json
    //__dirname:当前文件所处路径
    filePath = path.join(__dirname, filePath)//最后进行一次拼接获得可以被访问的路径

    try{
        //成功后响应头设置
        const ret = await fileUtils.getFileJsonData(filePath)//与utils文件建立联系
        //获取成功之后函数返回的对象:await
        ctx.response.body = ret
    } catch (error) {
        const errorMsg = {
            message:'读取文件内容失败,文件不存在!',
            status: 404
        }
        // ctx.response.body将errorMsg对象所形成的json格式的字符串
        ctx.response.body = JSON.stringify(errorMsg)
    }

    console.log(filePath)//打印filePath
   await next()//调用next函数,确保内层中间件得以执行
}

运行结果:
请添加图片描述

5.允许跨域

在实际问题中我们通常不会通过上述在浏览器中键入地址的形式访问网页,实际生活中是通过Ajax访问服务器

同源策略:同协议,同域名,同端口
(当前界面的地址与Ajax获取的地址相对应)
不遵守同源策略的后果:
当新建一个html文件后,通过其button按钮访问http://127.0.0.1:8888/api/trend报错

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="lib/jquery-1.12.2.js"></script>
</head>
<body>
    <button>点我试试</button>
    <!--  需响应按钮的点击事件,发起Ajax请求 -->
    <script>
    //通过选择器的方式,找到button按钮,响应点击事件
    //在点击事件处理函数function()中发起AJjax请求
    $('button').click(function (){
    //发起Ajax请求:例如:获取http://127.0.0.1:8888/api/trend中的数据
        $.ajax({
            type:'get',
            //同源策略是指:index下的域名应与app.js下的域名满足同源策略才可以在按钮中访问
            url:'http://127.0.0.1:8888/api/trend',
            success:function (data){
                console.log(data)
            }
        })
    })
    </script>
</body>
</html>

请添加图片描述
解决策略:
在koa_response_header.js文件中添加中间件

    //配置跨域请求响应头(同源策略实现)
    ctx.set("Access-Control-Allow-Origin", "*")
    ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE")

具体代码实现:

//设置响应头中间件
module.exports = async (ctx,next) => {
    const contentType = 'application/json; charset=utf-8'//??
    //通过ctx.set()设置响应头
    ctx.set('Content-Type', contentType)//??
    //展示效果:设置json格式的字符串
    //ctx.response.body = '{"success": true}'

    //配置跨域请求响应头(同源策略实现)
    ctx.set("Access-Control-Allow-Origin", "*")
    ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE")

    //为使中间件得到执行需调用next()函数
    await next();
}

运行结果:
请添加图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是手把手带你搭建koa2 mysql项目的教程。 1. 安装Node.js和npm 首先需要安装Node.js和npm,可以在官网下载安装包进行安装。 2. 初始化项目 在命令行进入项目目录,运行以下命令初始化项目: ``` npm init ``` 根据提示填写项目信息,完成后会生成package.json文件。 3. 安装koa2和koa-router 运行以下命令安装koa2和koa-router: ``` npm install koa koa-router --save ``` 4. 安装mysql模块 运行以下命令安装mysql模块: ``` npm install mysql --save ``` 5. 创建数据库 在mysql创建一个名为test的数据库,并创建一个名为users的表,包含id、name、age三个字段。 6. 创建连接池 在项目创建一个db.js文件,用于创建mysql连接池: ```javascript const mysql = require('mysql'); const pool = mysql.createPool({ host: 'localhost', user: 'root', password: '123456', database: 'test' }); module.exports = pool; ``` 7. 创建路由 在项目创建一个router.js文件,用于创建koa-router路由: ```javascript const Router = require('koa-router'); const pool = require('./db'); const router = new Router(); router.get('/users', async (ctx) => { const conn = await pool.getConnection(); const [rows] = await conn.query('SELECT * FROM users'); conn.release(); ctx.body = rows; }); module.exports = router; ``` 8. 创建服务器 在项目创建一个app.js文件,用于创建koa2服务器并引入路由: ```javascript const Koa = require('koa'); const router = require('./router'); const app = new Koa(); app.use(router.routes()); app.listen(3000, () => { console.log('Server is running at http://localhost:3000'); }); ``` 9. 运行项目 在命令行进入项目目录,运行以下命令启动服务器: ``` node app.js ``` 在浏览器访问http://localhost:3000/users,可以看到数据库的用户数据。 至此,一个简单的koa2 mysql项目就搭建完成了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值