4.13 -react脚手架配置代理-Echarts-Koa2的快速上手-中间件的开发-跨域配置
一.学习内容
1.1 react脚手架配置代理
1.方法一:直接在package.json中配置
优点:配置简单,前端请求资源时可以不加任何前缀。
缺点:不能配置多个代理。
"proxy":"http://localhost:5000"
2.方法二:
优点:可以配置多个代理,可以灵活的控制请求是否走代理。
缺点:配置繁琐,前端请求资源时必须加前缀。
-
第一步:创建代理配置文件, 文件名不可以修改,该文件不需要导入,react内部可以自动处理
在src下创建配置文件:src/setupProxy.js
-
编写setupProxy.js配置具体代理规则:
const {createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { app.use( proxy('/api1', { //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000) target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址) changeOrigin: true, //控制服务器接收到的请求头中host字段的值 /* changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000 changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000 changeOrigin默认值为false,但我们一般将changeOrigin值设为true */ pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置) }), proxy('/api2', { target: 'http://localhost:5001', changeOrigin: true, pathRewrite: {'^/api2': ''} }) ) }
1.2 Echarts-Koa2的快速上手
KOA2: 是基于 Node.js 平台的Web服务器更加轻量级的框架 ,有更强的异步处理能力使用async,和await进行处理。并且是自己封装请求和响应对象。
功能::可以接收浏览器发送的HTTP请求,接收到对应的请求后,可以对请求进行解析,解析完后对相应的内容进行处理,处理完成后会将处理的结果返回给浏览器,也就是返回响应内容。(解析过程中使用到一些中间件)
特点:支持async,await;koa的某一个中间件可以自行选择之后中间件的执行位置的,Koa
采用洋葱圈模式处理中间件的嵌套和执行顺序。
KOA中间件:是一个async函数,app.use((ctx , next) => { next() })
,通过调用 next()
则该函数暂停并将控制传递给定义的下一个中间件。
ctx: 上下文对象,web容器,ctx.request:koa自己封装的request对象;ctx.response:koa自己封装的response对象
洋葱圈模式:是先重外层执行到内层,执行内层再重内层依次执行到最外层。
使用:
1.检查Node.js的环境 node -v. 注意:该版本必须在v7.6.0 及以上 ,由于 Koa2 它是支持 async 和 await ,node.js 从v7.6.0开始完全支持async/await。
2.初始化package.json: npm init -y
3.安装Kao :npm install koa
4.创建并编写app.js文件
//创建Kao对象
const Koa= require('koa')
const app=new Koa()
//编写响应函数中间件
app.use((ctx,next)=>{
//设置响应体
ctx.response.body='hello world'
console.log('第一层中间件')
//内层中间件能否执行取决于外层中间件的next函数是否调用
next()
})
app.use(async (ctx,next)=>{
console.log('第二层中间件')
const s=await next()
console.log(s)
})
app.use((ctx,next)=>{
console.log('第三层中间件')
return 'strueijbnkkl'
})
//监听端口号
app.listen(3000)
1.3 中间件的开发
1.3.1 响应完成总耗时中间件的开发
1.创建一个文件夹用于存取所有的中间件middleware,并创建总耗时中间件koa_response_data.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')
}
1.3.2 设置响应头的中间件
1.创建响应头的中间件koa_response_header.js文件
// 设置响应头的中间件
module.exports = async (ctx, next) => {
const contentType = 'application/json; charset=utf-8'
ctx.set('Content-Type', contentType)
await next()
}
1.3.3 处理业务逻辑的中间件,用于读取某个json文件的数据
// 处理业务逻辑的中间件,读取某个json文件的数据
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)
}
await next()
}
2.创建一个文件file_utils.js,写入读取文件的方法,返回Promise对象,对文件进行异步处理,对文件读取成功或者失败返回相应的状态值。
// 读取文件的工具方法
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)
}
})
})
}
最后将三个中间件进行引入app.js,并绑定
// 服务器的入口文件
// 1.创建KOA的实例对象
const Koa = require('koa')
const app = new Koa()
// 2.绑定中间件
// 绑定第一层中间件
const respDurationMiddleware = require('./middleware/koa_response_duration')
app.use(respDurationMiddleware)
// 绑定第二层中间件
const respHeaderMiddleware = require('./middleware/koa_response_header')
app.use(respHeaderMiddleware)
// 绑定第三层中间件
const respDataMiddleware = require('./middleware/koa_response_data')
app.use(respDataMiddleware)
// 3.绑定端口号 8888
app.listen(8888)
1.3.4 跨域配置
在响应头中间件中配置
// 设置响应头的中间件
module.exports = async (ctx, next) => {
const contentType = 'application/json; charset=utf-8'
ctx.set('Content-Type', contentType)
//跨域配置
ctx.set("Access-Control-Allow-Origin", "*")
ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE")
await next()
}
二.扩展学习
1.module.exports和export
它是Node.js提供的一个简单的模块系统,两者的区别: exports 只能对外暴露单个函数,但是 module.exports 却能暴露一个类。
Node.js 提供了 exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口.
1)exports使用
导出模块
var sayHello = function () {
console.log('hello')
}
//导出一个方法
exports.sayHello = sayHello;
引入模块
var hello = require('./hello');
2)module.exports 的使用
导出模块
function Hello() {
var name;
var sos = '110';
this.sayHello = function () {
console.log('Hello ' + name);
};
};
// 把变量、方法等封装在一起,一并导出
module.exports = Hello;
引入模块
var hello = require('./hello')
//调用模块hello中的方法
hello.sayHello();