Koa下http代理

栏目: Node.js · 发布时间: 6年前

内容简介:最近做管理后台的重构或者说重做. 至于为什么要重构.随意的解释:客观的解释:

最近做管理后台的重构或者说重做. 至于为什么要重构.

随意的解释:

  1. 是原来写的人走了.

客观的解释:

  1. 用的人觉得不好用
  2. 维护的人员找不到北

再多一点解释:

  1. express + ejs的混合编写
    • 单独抽象了Router层, 定义了controller层, service层, 但是强行绑定, 耦合很紧密
    • 中间件过度使用, 本意想简化操作, 反而编程负担
    • 服务端定义了渲染模板, 前端又有模板, 额
    • 引入ts, 但是很多都是any, 接口很多都是直接把query或者body参数直接使用, 非常难跟踪数据
    • views未按照功能分文件夹, 全部在一个文件夹下, 头晕的厉害
    • 后台配置不合理, 即使是菜单这种配置也是完全一样的几份
  2. 前端杂乱
    • jquery编写, 本身并无问题, 没有模块化, 出现代码多页面混用, 一处修改, 可能多页面出错
    • 体验很差, 测试人员和开发人员都不一定能正常操作

额外说两句, 这里的express + ejs的项目属于前端项目, 后台有很多nodejs编写的形式微服务的服务.

因为是后台管理项目, 美观要求并不是那么高. 我的规划是.

基于koa的node中间层

  1. 授权管理
  2. ACL管理, 这里我们自己编写的轻量级的权限控制.
  3. 文件上传(阿里) 和其他可能需要定制的处理, 比如使用文件批量上传数据的处理
  4. 请求转发

前端项目

使用 create-react-app + react-app-rewired + ant + mobx 构建项目,

ant design已经基本够用, 实际上mobx都可以不用.

这里就有两个项目项目了, 一个ui项目, 一个中间层api项目.

开发模式下, ui项目是通过dev-server启动的, 会通过代理转发请求到中间层api项目, 中间层api项目再转发到实际的服务. 这一切看起来都很美好, 也没毛病.

问题

我随手拈来, 配置好, 开始请求. 就泪奔了. 请求死活过不去.

各种中间件尝试

express下面有很好用的http-proxy-middleware, 但是koa并没有, koa官方推荐的是koa-proxies 和koa-better-http-proxy, 自己搜索发现 koa-proxy下载量和star都还要高一些, 于是自己就开始挨个试试, 均失败.

开始怀疑是版本问题, 查看均是支持的, 而且debug确实执行了请求发送, debug进入源码发现 Socket hang up.

自己封装

后来检查源码, 其实都是基于http-proxy进行的封装, 于是参考别人的代码, 自己简单的封装了一个版本, 进行debug, 结果依旧,

koa-connect

后来搜索发现, koa下能使用express的中间件, 需要通过转换, 这个中间件就是koa-connect, 于是进行切换, 结果还是失败, 心疼

http-proxy 生命周期拦截

接着尝试, 在http-proxy的各个生命周期进行拦截, 成效也不大, 倒是了解了一下http-proxy

x-www-form-urlencoded

我们的接口全部都是post调用的,而且接受的数据格式都是x-www-form-urlencoded, 偶尔一次发现, 使用get居然转发到了服务器, 只是提示不允许get调用, 其实说明已经能联通, 但是post却是过不去. 那就说明问题很可能处在数据传递的格式.

百度,bing和google搜索

发现了这篇文章,

http-proxy-middleware nodejs post请求超时问题 x-www-form-urlencoded

我把代码提前了, 结果真的是ok了, 我的眼泪啊.

但是, 不能这样啊, 我的auth拦截肯定会先于proxy, auth之前肯定还有bodyParser, session等中间件, 大哥这可不行啊.

继续搜索 edit-post-parameters-prior-to-forwarding-to-a-proxy-target-and-sending-response

onProxyReq(proxyReq, req, res) {
     if ( req.method == "POST" && req.body ) {
         // Add req.body logic here if needed....

        // ....

         // Remove body-parser body object from the request
         if ( req.body ) delete req.body;

         // Make any needed POST parameter changes
         let body = new Object();

         body.filename = 'reports/statistics/summary_2016.pdf';
         body.routeid = 's003b012d002';
         body.authid = 'bac02c1d-258a-4177-9da6-862580154960';

         // URI encode JSON object
         body = Object.keys( body ).map(function( key ) {
             return encodeURIComponent( key ) + '=' + encodeURIComponent( 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();
     }
 }

看到重写了content-type和content-length, 我就笑了. 还是自己太天真, 没理解好这个onProxyReq方法, 于是我也这么重写, 再提前其他中间件, 就没有问题了.

我真的就能苦笑了, 还好解决了问题. 关于http-proxy打算有时间深入看一看, 值得拥有.


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning ASP.NET 4 in C# and Vb

Beginning ASP.NET 4 in C# and Vb

Imar Spaanjaars / Wrox / 2010-3-19 / GBP 29.99

This book is for anyone who wants to learn how to build rich and interactive web sites that run on the Microsoft platform. With the knowledge you gain from this book, you create a great foundation to ......一起来看看 《Beginning ASP.NET 4 in C# and Vb》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具