最近在学习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 请求转发实现相关推荐

  1. JSP中的重定向和请求转发以及它们的区别

    我们先硬着头皮看一下重定向的定义: 重定向(Redirect): 客户端浏览器向Web应用服务器端发送一个请求,Web服务器端使用HttpServletResponse的sendRedirect()方 ...

  2. jsp重定向与请求转发的路径404问题

    请求转发特点: 1. 浏览器地址栏路径不发生变化 还停留在首次访问的Servlet的URL 2. 只能转发到当前服务器内部资源中. 3. 转发是一次请求,可以使用request共享数据 4. 自我归纳 ...

  3. 3.相应重定向与请求转发的比较

    响应重定向与请求转发类似,但有下面的区别: (1)RequestDispatcher对象是一个Web资源的包装器,可以用来把当前请求转发到该资源.这种转发是服务器端控制权的转向,客户端发来的请求将交由 ...

  4. Servlet--06--解决乱码问题; 请求转发; 重定向;

    乱码问题: 一.  请求-乱码问题:服务器获取的请求数据,在console显示时,出现了乱码. (1)post请求方式解决:req.serCharacterEncoding("utf-8&q ...

  5. 请求转发与请求重定向

    请求重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保持,地址栏的URL地址会改变. 请求转发:服务器行为,request.getRe ...

  6. JAVA记录-Servlet RequestDispatcher请求转发

    RequestDispatcher接口提供将请求转发送到另一个资源的功能,它可能是html,servlet或jsp等. 此接口也可用于包括另一资源的内容.它是servlet协作的一种方式. 在Requ ...

  7. jsp:请求转发和重定向

    HttpServletResponse对象的sendRedirect(String location)方法称作重定向, 如果location地址前面加上"/",则表示相对于Serv ...

  8. JSP的学习二(请求转发与 重定向)

    一: 1.介绍知识点 1). 本质区别: 请求的转发只发出了一次请求, 而重定向则发出了两次请求. 具体: ①. 请求的转发: 地址栏是初次发出请求的地址.  请求的重定向: 地址栏不再是初次发出的请 ...

  9. 015_请求转发和重定向

    一. 重定向和转发工程 1. 新建一个SendRedirectForward的Web工程 2. 在WebContent下新建index.html和success.html 3. 编写index.htm ...

  10. 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 ...

最新文章

  1. 年终盘点篇:2018年开源市场5大发展趋势
  2. webSocket使用心跳包实现断线重连
  3. C# vb.net 分别引用C++编译DLL
  4. 简练软考知识点整理-控制范围
  5. cmd xcopy 拷贝文件夹_在纯dos下用xcopy命令怎么复制文件夹
  6. angular使用Md5加密
  7. c#发送简单的post、get请求
  8. python创建实例会调用哪些魔术方法_Python最会变魔术的魔术方法,我觉得是它!...
  9. python3 rrdtool 使用
  10. mysql获取ddl的语句,获取数据库或SHEME的DDL语句
  11. 使用UniWeibo实现Unity3d里分享到新浪微博功能
  12. 一种简单的睡眠评分规则
  13. 计算 arccos 7
  14. css3中transform:translateY之后文字模糊的原因
  15. 微型计算机原理与接口选择题,2010年4月全国自考(微型计算机原理与接口技术)真题试卷...
  16. Go 快速起步:创建 WebSocket 服务器(聊天室)
  17. 联想sr650安装centos_联想SR650安装windowsserver2008R2系统
  18. PYQT5 +python3打造文本编辑器
  19. MathType在Word的菜单栏中不显示应该怎么解决
  20. Git分布式版本控制工具

热门文章

  1. 移动宽带断网 服务器没有响应,移动宽带卡终于解决了(移动宽带间歇性断网)...
  2. ​自动驾驶测试与验证的挑战
  3. 控制Tello无人机扫描条形码
  4. 计算机ps基础知识教案范文,ps基础教案
  5. 使用H5编写网页版象棋(源码)
  6. Cesium 获取屏幕窗口经纬度范围(2D和3D)
  7. 西门子200PLC指令详解——比较指令
  8. python第四天 组合数据类型 文件与数据格式化
  9. 4、那智机器人显示画面的构成和含义
  10. python———两个栈实现一个队列