- 需求背景利用nodejs和consul实现注册中心和网关
- egg.js在获取配置信息与节点后进行服务转发与路径管理
- 实现难点没有成行的技术博客去解决这个问题
解决方案
-
依赖http-proxy-middleware和koa2-connect
-
重点问题application/x-www-form-urlencoded 转发代理要定制解决否则活转发失败
-
配置文件中添加代理配置信息
-
// 忽略安全威胁csrf的防范
config.security = {
csrf:{
enable: false
} } //代理配置信息 config.proxyConfig = {};
// add your middleware config here config.middleware = ['proxy']; -
在中间件中添加代理js
-
proxy.js /* * @Description: api 网关代理 * @Author: 吴文周 * @Github: gitlab.yzf.net/wuwenzhou * @Date: 2020-06-28 13:38:19 * @LastEditors: 吴文周 * @LastEditTime: 2020-08-13 18:14:32 */ const { createProxyMiddleware } = require('http-proxy-middleware'); const k2c = require('koa2-connect'); module.exports = (options,app) => {
return async function(ctx,next) { let proxy= app.config.proxyConfig;
try {
const Proxy = k2c(createProxyMiddleware('/api',{ target: proxy.target,// 动态设置可以从缓存中获取更新
pathRewrite:proxy.Rewrite,// 动态设置可以从缓存中获取更新
changeOrigin: true,
secure: false,
body:ctx.request.body,
onProxyReq:(proxyReq, req, res, options)=>{
const contentType = proxyReq.getHeader('Content-Type'); // 特殊判断如果类型是application/x-www-form-urlencoded 转发代理需要特殊处理
try {
if (contentType && contentType.indexOf('application/x-www-form-urlencoded')>=0) { let body = Object.keys(options.body).map(function(key) {
return encodeURIComponent( key ) + '=' + encodeURIComponent(options.body[key]) }).join('&');
//Update header
proxyReq.setHeader('content-type', 'application/x-www-form-urlencoded');
proxyReq.setHeader('content-length', body.length );
// Write out body changes to the proxyReq stream
proxyReq.write(body);
// proxyReq.end();
}
} catch (error) {
console.log(error); } } }));
await Proxy(ctx,next); }else{ next() } } catch (error) { console.log(error) next() } };};