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是读取文件的文件名,如果是相对 ...
随机推荐
- Maven生成可以直接运行的jar包的多种方式
Maven可以使用mvn package指令对项目进行打包,如果使用Java -jar xxx.jar执行运行jar文件,会出现"no main manifest attribute, in ...
- Java8 Stream简介
Stream是Java 8新增的重要特性, 它提供函数式编程支持并允许以管道方式操作集合. 流操作会遍历数据源, 使用管道式操作处理数据后生成结果集合, 这个过程通常不会对数据源造成影响. lambd ...
- SSL证书:Web加密使互联网更安全
在网络安全的圈子里,我们都会隔三差五的听到某某公司遭受恶意软件攻击.或大量的隐私信息被泄露等等事件,此类安全事件往往都有影响范围广.涉及用户众多等特点.不免让人质疑联网的世界越来越危险.然而,在安全专 ...
- MQ、JMS以及ActiveMQ 关系的理解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt127 Best-text mb-10代码 ms 的一个标准或者说是一个协议. ...
- setTimeout,setInterval你不知道的…
javascript线程解释(setTimeout,setInterval你不知道的事) 标签: javascript引擎任务浏览器functionxmlhttprequest 2011-11-21 ...
- go golang 笔试题 面试题 笔试 面试
go golang 笔试题 面试题 笔试 面试 发现go的笔试题目和面试题目还都是比较少的,于是乎就打算最近总结一下.虽然都不难,但是如果没有准备猛地遇到了还是挺容易踩坑的. 就是几个简单的笔试题目, ...
- 团队作业4——第一次项目冲刺 fOURth DaY
项目冲刺--Quadra Kill 兄弟们,再坚持一下,再坚持一下,再给我一个头我就五杀了. 今天可谓是项目的一个转折点,因为跳转和数据库已经基本写好啦,鼓掌~[啪啪啪啪啪啪] 让我们来看看今天大家做 ...
- 201521123057 《Java程序设计》第2周学习总结
1. 本章学习总结 本周Java教学主要围绕Java的基本语法展开.在本周的学习中,我了解到了: -Integer的取值范围 -if...else条件式,switch条件式,while循环,break ...
- 201521123047《Java程序设计》第1周学习总结
1. 本章学习总结 学习到了jdk,jvm,jre之间的关系,下载并安装了jdk,学会设置path变量,初步学会建立简单的java程序,并执行成功.初步学会notepad++,eclipse的操作.学 ...
- 201521123008《Java程序设计》第1周学习总结
本周学习总结 了解了JAVA:jdk:jre:jvm等 C语音与JAVA的部分区别: C语言全面向过程,java面向对象: C语言的代码不能跨平台,java的代码可以跨平台: C语言有指针,java没 ...