nodejs中http-proxy使用小结

Posted 无梦灬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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使用小结的主要内容,如果未能解决你的问题,请参考以下文章

在本地设置 http-proxy 代理 (前后端分离)

nodejs常用代码片段

使用 NodeJS 和 JSDOM/jQuery 从代码片段构建 PHP 页面

Node.js - 使用 Express 和 http-proxy 进行反向代理

javascript 用于在节点#nodejs #javascript内设置react app的代码片段

http-proxy 有问题