Hapi.js代理 - 在回复之前更改响应

时间:2015-02-01 13:23:04

标签: javascript node.js hapijs

我正在尝试测试Hapi.js我正在开发的新项目 我的目标是在我的Hapi服务器上触发请求,此请求将使用Hapi代理在远程服务器上触发另一个请求,响应将只是来自远程响应的特定属性

要对此进行测试,必须发出对/ api / type3 / name的请求,该请求将调用对GitHub API的API调用以获取用户对象

代码:

server.route({
    method: 'GET',
    path: '/api/type3/{name}',
    handler: {
      proxy: {
        mapUri: function(request,callback){
            callback(null,'https://api.github.com/users/'+request.params.name);
        },
        onResponse: function(err, res, request, reply, settings, ttl){
           console.log(res); 
           reply(res);
        },
        passThrough: true,
        xforward: true
      }
    }
});

上面代码的响应是来自GitHub的响应对象 现在我需要保存此响应,以便我可以操作它并仅返回我需要的内容

但是,当我调试响应对象时,它包含大量数据,而我无法在其中找到响应有效负载

那么如何从响应对象中仅提取GitHub的响应?

非常感谢

3 个答案:

答案 0 :(得分:4)

在上面的残骸案例中,你可以做到

payload = payload.toString();

将缓冲区转换为实际数据。

答案 1 :(得分:3)

res对象是http.IncomingMessage。如果你想使用响应的主体,你需要首先读取它的所有数据。

你有2个选择。

1)香草节点

onResponse: function(err, res, request, reply, settings, ttl){

    var body = '';

    res.on('data', function (chunk) {
        body += chunk;
    });

    res.on('end', function () {
        console.log(body);  
        reply(body);
    });
}

2)使用Wreck(Hapi人员在Node中处理HTTP的模块)

var Wreck = require('wreck');

onResponse: function(err, res, request, reply, settings, ttl){
   Wreck.read(res, null, function (err, payload) {
       console.log(payload);
       reply(payload);
   });
}

答案 2 :(得分:3)

我想从远程服务器加载xml数据并将响应转换为json。 这个帖子帮助我找到了一个对我有用的解决方案。但就我而言,上面的代码也不起作用,因为远程服务器的响应是gzip压缩的。在我的控制台中,只有不可读的数据。

我尝试为代理启用自动有效负载解析,但是没有成功。最后,我必须自己用“zlib'。

解压缩回复。”

此代码对我有用:

'use strict'

const url = require('url')
const h2o2 = require('h2o2')
const Hapi = require('hapi')
const parseString = require('xml2js').parseString
var zlib = require('zlib')
const _ = require('lodash')

var remoteServerUrl = 'http://some-url.com:2434'
var originUrl = 'http://localhost:3000'

// Create a server with a host and port
const server = new Hapi.Server()
server.connection({
  host: 'localhost',
  port: 3001,
  routes: {
    cors: {
      origin: [originUrl],
    },
  },
})

server.register({
  register: h2o2,
}, function (err) {
  server.start(function (err) {
    console.log('Proxy Server started at: ' + server.info.uri)
  })
})

server.route({
  method: '*',
  path: '/proxy/{path*}',

  config: {
    payload: {
      // parse: true,   // didn't worked for me
      // parse: 'gzip', // didn't worked for me
      output: 'stream',
    },
  },

  handler: {

    proxy: {
      passThrough: true,
      timeout: 15000,
      acceptEncoding: false,

      mapUri (request, callback) {
        callback(null, url.format({
          protocol: url.parse(remoteServerUrl).protocol,
          host: url.parse(remoteServerUrl).host,
          port: url.parse(remoteServerUrl).port,
          pathname: request.params.path,
          query: request.query,
        }))
      },

      onResponse (err, res, request, reply, settings, ttl) {
        if (err) {
          console.error('Hapi server error: ', err)
        }

        // let's unzip the response 
        var gunzip = zlib.createGunzip()
        var xmlStr = ''

        gunzip.on('data', function (data) {
          xmlStr += data.toString()
        })

        gunzip.on('end', function () {
          // do something with the string
          // in this case convert xml to json string
          parseString(xmlStr, {}, function (err, result) {
            // send result back
            reply(result)
          })
        })

        res.pipe(gunzip)
      },
    },
  },
})

也许这有助于其他人;)