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是读取文件的文件名,如果是相对 ...
随机推荐
- C# 单例模式(Singleton Pattern)(转SuagrMatl)
单例模式的定义: 确保一个类只有一个实例,并提供一个全局访问点. 首先实例大家应该都明白就是类生成对象的过程简单的就是String s=new String(),则s就是个实例. Q:如何只生成一个实 ...
- 《Java从入门到放弃》JavaSE入门篇:面向对象语法二(入门版)
想了半天,发现单独的封装和多态没什么好讲的,我们就简单说说Java里面对应的语法吧. 相关内容如下: 一.访问修饰符 二.getter/setter方法 三.构造方法 四.super和this 五.s ...
- 【前端基础】动态脚本与JSONP
博主入职两个月了,越来越感受到打好基础对于前端工程师的重要性,在向着狂拽酷炫的框架&构建工具高速狂奔之前,必须有一个坚实的基础打底,才不至于轻易翻车.所以博主最近一直在恶补<JS高级程序 ...
- 关于时间对象Date()
今天使用XCUI开发过程中发现另一个诡异的问题,就是年月日初始化之后默认时分秒的问题. 问题发生在重构交互日志页面的时候,原来的老页面是这样的: 进入了交互日志页面之后,默认会初始化时间为今天的凌晨到 ...
- cat、tail、head、tee、grep、wc、sort文件操作和过滤
详见;http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt103 文件操作和过滤 绝大多数命令行工作是针对文件的.我们会在本节中讨论如何 ...
- el表达式里面fn的用法
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp31 头部加入标签库 <%@ taglib prefix=" ...
- String.equals()方法
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
- 第3阶段——内核启动分析之创建si工程和分析stext启动内核函数(4)
目标: (1)创建Source Insight 工程,方便后面分析如何启动内核的 (2)分析uboot传递参数,链接脚本如何进入stext的 (3) 分析stext函数如何启动内核: (3.1) ...
- VHDL学习:利用Quartus自带库3步快速完成状态机
Quartus自带库里面有各种编程语言的模板,供开发者参考. 初学者利用VHDL实现状态机比较生疏的情况下,可以调出该模板,适当修改即可. 本文将描述如何利用Quartus自带库调出状态机模板,并适当 ...
- 大数的减法函数--c语言
代码展示: http://paste.ubuntu.com/23693598/ #include<stdio.h> #include<stdlib.h> #include& ...