前言

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

随意的解释:

  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打算有时间深入看一看, 值得拥有.

Koa下http代理的更多相关文章

  1. linux下正向代理/反向代理/透明代理使用说明

    代理服务技术对于网站架构部署时非常重要的,一般实现代理技术的方式就是在服务器上安装代理服务软件,让其成为一个代理服务器,从而实现代理技术.常用的代理技术分为正向代理.反向代理和透明代理.以下就是针对这 ...

  2. windows下使用代理连接github

    在公司的windows下使用github,因为github被墙,查了查,发现给在windows下的git制定代理很简单,一句话   git config --global http.proxy htt ...

  3. pip在windows域下使用代理安装package方法

    首先说明下,本人在公司使用windows域账户代理上网,用pip在线安装package 返回ProxyError,类似Tunnel connection failed: 407 authenticat ...

  4. linux命令行模式下实现代理上网

    有些公司的局域网环境,例如我们公司的只允许使用代理上网,图形界面的很好解决就设置一下浏览器的代理就好了,但是linux纯命令行的界面就....下面简单几步就可以实现了! 一.命令行界面的一般代理设置方 ...

  5. linux命令行模式下实现代理上网(转)

    有些公司的局域网环境,例如我们公司的只允许使用代理上网,图形界面的很好解决就设置一下浏览器的代理就好了,但是linux纯命令行的界面就....下面简单几步就可以实现了! 一.命令行界面的一般代理设置方 ...

  6. 在Linux终端下使用代理访问网络(转)

    最近,需要在linux环境下使用脚本进行一些网络访问(主要是HTTP请求与文件下载),于是查阅了一些关于代理的资料. 以下是尝试的几种代理设置方法,以供参考: 一.使用wget命令进行代理访问 wge ...

  7. windows下nginx代理ftp服务器

    我所在的开发环境里,nginx和ftp在同一台服务器. ftp根目录: nginx的配置: 在nginx.conf中加入: server { listen ; server_name localhos ...

  8. Mac OSX系统下通过ProxyChains-NG实现终端下的代理

    项目主页:https://github.com/rofl0r/proxychains-ng 官方说明: proxychains ng (new generation) - a preloader wh ...

  9. 解决CentOS内网机通过Windows下架设代理来访问网络

    新分配的CentOS运行在内网环境下,无法连接Internet,为了能够使用yum部署OpenVas工具,需要在内网下一台Windows主机架设代理,作代理服务器来令虚拟机上网. 代理服务器选择了CC ...

随机推荐

  1. android开发:Android 中自定义View的应用

    大家好我们今天的教程是在Android 教程中自定义View 的学习,对于初学着来说,他们习惯了Android 传统的页面布局方式,如下代码: <?xml version="1.0&q ...

  2. angular5 路由传参的几种方式

    此处介绍三种方式 方式一: 问号后面带的参数, 例如:/product?id=1&name=iphone还可以是: [routerLink]="['/books']" [q ...

  3. CDS & ORF & 启动子 & 终止子 & 转录因子 & 基因结构 & UTR

    ORF和CDS的区别 ORF的英文展开是open reading frame(开放阅读框). CDS的英文展开是coding sequences (编码区). CDS:DNA转录成mRNA,mRNA经 ...

  4. Java 的对象和类

    Java 是一种面向对象的语言.作为一个面向的语言,Java 具有面向对象的特性,Java 能够支持下面的一些基本概念 − 多态(Polymorphism) 继承(Inheritance) 封装(En ...

  5. Travelling Salesman and Special Numbers CodeForces - 914C (数位dp)

    大意: 对于一个数$x$, 每次操作可将$x$变为$x$二进制中1的个数 定义经过k次操作变为1的数为好数, 求$[1,n]$中有多少个好数 注意到n二进制位最大1000位, 经过一次操作后一定变为1 ...

  6. hdu-4417-主席树+离线

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. POJ-3259 Wormholes(判断负环、模板)

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  8. Java远程调试 java -Xdebug各参数说明

    JAVA自身支持调试功能,并提供了一个简单的调试工具--JDB,类似于功能强大的GDB,JDB也是一个字符界面的 调试环境,并支持设置断点,支持线程线级的调试 JAVA的调试方法如下: 1.首先支持J ...

  9. win32com问题

    py -3 -m pip install adodbapi win32com.__gen_path__, "dicts.dat" 问题解决       pip install xl ...

  10. 玩转控件:重绘DEVEXPRESS中DateEdit控件 —— 让DateEdit支持只选择年月 (提供源码下载)

      前言 上一篇博文<玩转控件:重绘ComboBox —— 让ComboBox多列显示>中,根据大家的回馈,ComboBox已经支持筛选了,更新见博文最后最后最后面.   奇葩 这两天遇到 ...