nodejs中http-proxy使用小结
最近在写xmocker的工具,用于开发前期的mock数据,不可避免的用到了代理的中间件。当然,github上有关于http-proxy封装的中间件。毕竟是自己练手的项目,就自己写了个中间件,方便定制功能。
http-proxy库用于koa中,是使用它的 proxy.web方法。常规的用法是:
proxy.web(req, res, { target: 'http://mytarget.com:8080' }, function(e) { ... });
项目中的要求是将API代理到用户填写的网址上去。Koa提供了req和res,用户提供了网址,这样中间件就很容易写了
function proxyTo({ status }) {
return async function (ctx, next) {
return next().then(async () => {
if (status === undefined || ctx.status === status) {
let data
try {
data = await proxy.web(ctx.req, ctx.res)
} catch (e) {
if (err) console.log(err)
return
}
}
})
}
}
设置访问结果为404则进行代理,否则不进行代理。然后在koa的中间件中use这个函数就可以了。
基础应用这样自然就可以了,可是遇到POST的时候就不行了,因为用到了koa-bodyparser,导致post的请求没法发给服务器。在http-proxy的issue中到处找解决办法,终于找到了让req重新stream的方法。
proxy.on('proxyReq', function (proxyReq, req, res, options) {
if (req.body) {
let bodyData = JSON.stringify(req.body)
// incase if content-type is application/x-www-form-urlencoded -> we need to change to application/json
proxyReq.setHeader('Content-Type', 'application/json')
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData))
// stream the content
proxyReq.write(bodyData)
}
})
嗯,这样基本就完成了一个Proxy的中间件。
刚开始用起来还不错,至少普通的API都可以转发了。于是试着代理到公司的API系统,网页端也没发现什么问题。然后用fiddler代理安卓客户端,用正则代理链接至自己的服务,出现了乱码。。。客户端用的是okhttp发出的请求,fiddler上看转发回来的json数据明明是正常的,结果在手机上中文就是不正确,都是十六进制代码,根本没解析。仔细对比:编码?都是utf-8,这个没问题。gzip?我明明是用的pipe过去,代码原封不动啊。我试中捕获了所有数据,用gzip解码后,也是正确的,那为什么会出错呢?
和别人交流了好久也没找到问题。没办法,到代码中找找。对于请求的header,发现cookie貌似少了一条,就看看header转发时候怎么处理的。结果发现,header全是进行转换的。issue中有提到set-cookie多条的问题,我这也是这个情况,尝试着看看这个文件改动记录,意外发现了一个Option项 :preserveHeaderKeyCase。
nodejs中header都是小写的形式,所以http-proxy中就进行了转换,将请求全部header转为小写。于是改了了true,这样就不再转换了。然后,客户端正常了!!!哈哈,仔细一看,cookie还是不是多条。算了,先不管cookie了,至少普通登录没啥问题了。
另外加个changeOrigin为true可以防止有些服务器path取的是初始域名,出现404的问题。暂时就这么多啦。proxy插件的地址在:
https://github.com/wenlonghuo/xmocker/blob/master/app/plugin/proxy.js
欢迎试用我的Mock工具:
https://github.com/wenlonghuo/xmocker-cli
nodejs中http-proxy使用小结的更多相关文章
- 在nodejs中利用 Proxy监听对象值的获取
1 window = new Proxy(global, { 2 get: function (target, key, receiver) { 3 console.log("window. ...
- nodejs中的require,exports使用说明
模块是一门语言编写大项目的基石,因此,了解如何组织.编写.编译.加载模块很重要.这里主要谈谈Node中的模块加载. 1.Node中的模块,主要使用require来加载模块,文件 require(&qu ...
- 示例 - 如何在NodeJS中调用SS生成的DLL
要想在NodeJS中调用SS生成的DLL, 需要借助EdgeJS. EdgeJS: http://tjanczuk.github.io/edge/ 如果你还不知道如何在SS中生成DLL, 请查看: S ...
- 使用 nodejs 中的 http 模块实现几个超实用的工具
nodejs 方便了我们前端开发者进行一些服务端上的操作,可以进行无缝地衔接.像其他一些后端语言,如 php, golang, java 等,都需要一定的学习成本,而 nodejs 则就是为前端开发者 ...
- nodejs中获取时间戳、时间差
Nodejs中获取时间戳的方法有很多种,例如: new Date().getTime() Date.now() process.uptime() process.hrtime() 平时想获取一个时间戳 ...
- 在Nodejs中如何调用C#的代码
最近需要在Nodejs中用到C#的代码,从网上了解到可以采用Edgejs来实现Nodejs与C#的代码交互, 直接复制网上的代码运行总是出各种错,填了不少坑,现在把自己的案例代码大致整理一下,方便以后 ...
- nodejs 中自定义事件
经常看到 req.on('error', function(){...}); 这种代码. 在nodejs中,可以使用 EventEmitter来实现. 具体的关键词有如下几个: var reqEven ...
- NodeJS中的异步I/O、事件驱动
nodejs的主要特点是单线程.异步I/O.事件驱动.让我们先大概了解一下这些名词的意思. 单线程 单线程是任务按照顺序执行的,并且每次只执行一个任务,只有前面的任务执行完成以后,后面的任务才执行.在 ...
- nodejs中Stream的理解
在nodejs中可以通过fs模块读写文件,我们来看下fs模块提供的接口: fs.readFile(filename, callback) 异步读取文件. filename是读取文件的文件名,如果是相对 ...
随机推荐
- LVDS/RGB转EDP稳定方案----NCS8801S
目前山寨平板市场已经进入白热化,同质化的竞争.厂商的利润被压得非常的薄.一味的价格战肯定会带来行业洗牌.差异化是许多厂商的选择,而其中一条重要的路子,就是采用高分辨率的down-grade屏.如苹果的 ...
- Linux io Model
socket阻塞与非阻塞,同步与异步 作者:huangguisu 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调 ...
- OpenID Connect:OAuth 2.0协议之上的简单身份层
OpenID Connect是什么?OpenID Connect(目前版本是1.0)是OAuth 2.0协议(可参考本人此篇:OAuth 2.0 / RCF6749 协议解读)之上的简单身份层,用 A ...
- css常用文本属性
[CSS常用文本属性] 1. 字体.字号类: ① font-weight: 字体粗细. bold-加粗.normal-正常.lighter-细体 也可以使用100-900数值,400表示normal, ...
- win7系统盘扩容后不识别修复方法
谢天谢地 终于在不重装系统的情况下,把C盘修复好了. win7系统,C盘之前是200G,使用中慢慢的就用完, 虽然把几乎所有的软件都移植到D盘了但是还是不能释放更多的空间.剩下60多G的空间,一般够用 ...
- Promise的用法
promise.then().promise.catch().Promise.all()... Promise 构造函数接受一个函数作为参数,该函数的2个参数分别是 resolve 和 reject. ...
- [ASP.NET MVC]笔记(二) 数据注解和验证
验证注解的使用 1.Required:必须字段 [Required] public string FirstName() { get; set; } 2.StringLength:长度限制,或是可选项 ...
- 安装python虚拟环境
虚拟环境: 之前安装python包的命令: sudo pip3 install 包名包的安装路径:/usr/local/lib/python3.5/dist-packages安装同一个包的不同版本,后 ...
- jvm系列 (五) ---类的加载机制
类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...
- Jsp与beetl的比较
首先介绍一下模板引擎的概念,是为了使用户界面与业务数据分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎,就会生成一个标准的html文档. Jsp全名是JavaServer Page,中文名叫 ...