koa2 请求转发实现
最近在学习vue3+nestjs,打算用这两个做一个博客(页面仔都喜欢做博客网站,我也一样!!)。为了节约时间,提高效率,博客网站的管理后台、数据统计页面我打算用之前做的基于vue2+kao2的项目。
那么这样就出现了一个问题:后台管理页面有两个服务,一个是之前做好的基于koa2的,一个是基于新东西nestjs的。这样就需要做请求服务的代理将不同的服务代理到对应的服务器上。
对于代理,有很多办法,前端配置代理,后端请求转发、网关处理等等。最后我选择了后端请求转发来处理。这样对原先的代码改动最少。
代码
直接上代码,屁话后面说
// 中间件 /middleware/httpProxy.js
const axios = require('axios');
const qs = require('qs');module.exports = (opts = {}) => {return (ctx, next) => {if (!ctx.httpProxy) {proxy(ctx, opts);}return next();};
};function proxy(ctx, opts) {ctx.httpProxy = (params = {}) => {params = Object.assign({}, { host: opts.apiHost || '' }, params);let reqParams = Object.assign({}, params, formatReqParams(ctx, params));if (reqParams.method.toUpperCase() !== 'GET') {reqParams.data = params.data || ctx.request.body;}// application/x-www-form-urlencoded形式转发参数乱码修改if (qs.stringify(ctx.request.body)) {reqParams = { ...reqParams, data: qs.stringify(ctx.request.body) };}delete reqParams.headers.host;return axios(reqParams).then(res => {const { data, headers } = res;setResCookies(ctx, headers);return data;}).catch(err => {// console.log(err)return err;});};
}
function setResCookies(ctx, headers) {const resCookies = headers['set-cookie'];if (!headers || !resCookies || !resCookies.length || resCookies.length <= 0 || !resCookies[0]) {return;}ctx.res._headers = ctx.res._headers || {};ctx.res._headerNames = ctx.res._headerNames || {};ctx.res._headers['set-cookie'] = ctx.res._headers['set-cookie'] || [];ctx.res._headers['set-cookie'] =ctx.res._headers['set-cookie'].concat && ctx.res._headers['set-cookie'].concat(resCookies);ctx.res._headerNames['set-cookie'] = 'set-cookie';
}/*** @param {} ctx koa当前执行上下文* @param {} params 请求参数*/
function formatReqParams(ctx, params) {let { url, method, headers, protocol } = ctx;const { host } = params;const hasProtocol = /(http|s):\/\//;url = params.url || url;method = params.method || method;protocol = hasProtocol.test(url) ? url.split(':')[0] : params.protocol || protocol;url = `${protocol}://${host}${url}`;delete params.host;return { url, method, protocol, headers };
}// 注册及使用 app.js
const httpProxy = require('./middleware/httpProxy');
// apiHost即是你要转发请求到后端的host,其他的参数可以参考axioshttps://github.com/axios/axios
// 请求转发中间件,暂时只支持转发到另一个地址
// TODO: 支持多转发
app.use(httpProxy({apiHost: 'localhost:5000' // 全局端口})
);// 在需要使用的地方调用中间件
// http://xxx:4000/nest/xx的请求会转发到http://xxx:3000/nest/xx
if (url.startsWith('/nest')) {const data = await ctx.httpProxy({host: 'localhost:3000' // 多代理,nest地址代理到localhost:3000});// 这里可以做一些请求之后需要处理的事情ctx.body = data;
}
使用说明及配置项
功能实现用到的依赖就一个axios,也没做别的魔改,所以配置参看axios
单转发
如果路由不做其他操作,只是简单的IP地址的转发
// 中间件注册
app.use(httpProxy({apiHost: 'localhost:5000' // 全局端口})
);// 使用
if (url.startsWith('/nest')) { // 路径匹配const data = await ctx.httpProxy();// 这里可以做一些请求之后需要处理的事情ctx.body = data;
}
如果还有对接口地址进行修改的话
// 使用if (url.startsWith('/test')) {// 对url的处理// 。。。const data = await ctx.httpProxy({// url: '/nest/schedule'url: 'newUrl'});// 这里可以做一些请求之后需要处理的事情ctx.body = data;
}
多转发
A转发newA,B转发newB。。。
// 中间件注册
app.use(httpProxy());// 使用
if (url.startsWith('/nest')) {const data = await ctx.httpProxy({host: 'localhost:5000' // 多代理,nest地址代理到localhost:3000});// 这里可以做一些请求之后需要处理的事情ctx.body = data;} else if (url.startsWith('/test')) {const data = await ctx.httpProxy({host: 'localhost:3000', // 多代理,nest地址代理到localhost:3000});// 这里可以做一些请求之后需要处理的事情ctx.body = data;
}
还有一个代理的中间件:http-proxy-middleware。但是看介绍好像只能在express里用,koa没有案例提示。
这样就可以在任何地方里转发请求,比如鉴权之后,或者是之前写好的项目的某个地方,从而实现服务的扩展。对原来的服务改动的也少。
效果
koa服务在本地的4000端口,nestjs服务在3000端口
直接访问3000端口:
访问4000端口,进行端口转发
修改url后再转发
不足
这只是简单的使用axios进行请求转发,不是真正的代理
这就导致会出现一些意想不到的错误,就比如传递body参数的时候由于不是xxx=xxx&xxx=xxx形式,所以第二次接收body参数会出现乱码,像下面这样:
等实在代码洁癖犯了想想换种实现方法
koa2 请求转发实现相关推荐
- JSP中的重定向和请求转发以及它们的区别
我们先硬着头皮看一下重定向的定义: 重定向(Redirect): 客户端浏览器向Web应用服务器端发送一个请求,Web服务器端使用HttpServletResponse的sendRedirect()方 ...
- jsp重定向与请求转发的路径404问题
请求转发特点: 1. 浏览器地址栏路径不发生变化 还停留在首次访问的Servlet的URL 2. 只能转发到当前服务器内部资源中. 3. 转发是一次请求,可以使用request共享数据 4. 自我归纳 ...
- 3.相应重定向与请求转发的比较
响应重定向与请求转发类似,但有下面的区别: (1)RequestDispatcher对象是一个Web资源的包装器,可以用来把当前请求转发到该资源.这种转发是服务器端控制权的转向,客户端发来的请求将交由 ...
- Servlet--06--解决乱码问题; 请求转发; 重定向;
乱码问题: 一. 请求-乱码问题:服务器获取的请求数据,在console显示时,出现了乱码. (1)post请求方式解决:req.serCharacterEncoding("utf-8&q ...
- 请求转发与请求重定向
请求重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保持,地址栏的URL地址会改变. 请求转发:服务器行为,request.getRe ...
- JAVA记录-Servlet RequestDispatcher请求转发
RequestDispatcher接口提供将请求转发送到另一个资源的功能,它可能是html,servlet或jsp等. 此接口也可用于包括另一资源的内容.它是servlet协作的一种方式. 在Requ ...
- jsp:请求转发和重定向
HttpServletResponse对象的sendRedirect(String location)方法称作重定向, 如果location地址前面加上"/",则表示相对于Serv ...
- JSP的学习二(请求转发与 重定向)
一: 1.介绍知识点 1). 本质区别: 请求的转发只发出了一次请求, 而重定向则发出了两次请求. 具体: ①. 请求的转发: 地址栏是初次发出请求的地址. 请求的重定向: 地址栏不再是初次发出的请 ...
- 015_请求转发和重定向
一. 重定向和转发工程 1. 新建一个SendRedirectForward的Web工程 2. 在WebContent下新建index.html和success.html 3. 编写index.htm ...
- nginx-启动gzip、虚拟主机、请求转发、负载均衡
一.启用gzip 1 gzip on; 2 gzip_min_length 1k; 3 gzip_buffers 4 16k; 4 gzip_http_version 1.1; 5 gzip_comp ...
最新文章
- 年终盘点篇:2018年开源市场5大发展趋势
- webSocket使用心跳包实现断线重连
- C# vb.net 分别引用C++编译DLL
- 简练软考知识点整理-控制范围
- cmd xcopy 拷贝文件夹_在纯dos下用xcopy命令怎么复制文件夹
- angular使用Md5加密
- c#发送简单的post、get请求
- python创建实例会调用哪些魔术方法_Python最会变魔术的魔术方法,我觉得是它!...
- python3 rrdtool 使用
- mysql获取ddl的语句,获取数据库或SHEME的DDL语句
- 使用UniWeibo实现Unity3d里分享到新浪微博功能
- 一种简单的睡眠评分规则
- 计算 arccos 7
- css3中transform:translateY之后文字模糊的原因
- 微型计算机原理与接口选择题,2010年4月全国自考(微型计算机原理与接口技术)真题试卷...
- Go 快速起步:创建 WebSocket 服务器(聊天室)
- 联想sr650安装centos_联想SR650安装windowsserver2008R2系统
- PYQT5 +python3打造文本编辑器
- MathType在Word的菜单栏中不显示应该怎么解决
- Git分布式版本控制工具