在管道之前编辑响应标头

时间:2014-07-30 17:01:41

标签: node.js express

我在Express中有一些小代理请求。使用request库,我有相当简洁的代码:

app.use('/api', function(req, res) {
    var url = rewriteUrl(req.url);

    var newReq = request(url, function(error) {
        if (error) {
            logError(error);
        }
    });

    req.pipe(newReq).pipe(res);
});

我的问题是来自API服务器的响应包含一堆我想要删除的不需要的标头。如何在将newReq传输到res之前从{{1}}的响应中删除标题?

4 个答案:

答案 0 :(得分:58)

mscdex的回答确实对我有用,但我找到了一种我认为稍微清洁的方法。在我的原始代码中,我有这一行:

req.pipe(newReq).pipe(res);

我用这些代替了它:

req.pipe(newReq).on('response', function(res) {
    delete res.headers['user-agent'];
    // ...
}).pipe(res);

答案 1 :(得分:15)

使用request模块,目前没有办法(AFAIK)进行回调而不缓冲服务器响应。因此,您可以使用内置的http.request

来完成此操作
app.use('/api', function(req, res) {
  var url = rewriteUrl(req.url);

  var newReq = http.request(url, function(newRes) {
    var headers = newRes.headers;

    // modify `headers` here ...

    res.writeHead(newRes.statusCode, headers);
    newRes.pipe(res);
  }).on('error', function(err) {
    res.statusCode = 500;
    res.end();
  });

  req.pipe(newReq);
});

答案 2 :(得分:4)

请求很容易。

const MembershipType = new GraphQLObjectType({
  name: 'Membership',
  interfaces: [nodeInterface],

  fields: {
    id: globalIdField(),

    user: {
      type: new GraphQLNonNull(UserType),
      resolve(parent, args, ctx: Context) {
        return ctx.userById.load(parent.user_id);
      },
    },

    role: {
      type: new GraphQLNonNull(GraphQLString),
    },

    team: {
      type: GraphQLString,
    },

    createdAt: {
      type: new GraphQLNonNull(GraphQLString),
      resolve(parent) {
        return parent.created_at;
      },
    },

    updatedAt: {
      type: new GraphQLNonNull(GraphQLString),
      resolve(parent) {
        return parent.updated_at;
      },
    },
  },
});

export default MembershipType;


const UserType = new GraphQLObjectType({
  name: 'User',
  interfaces: [nodeInterface],

  fields: {
    id: globalIdField(),

    firstName: {
      type: GraphQLString,
      resolve(parent) {
        return parent.first_name;
      },
    },

    lastName: {
      type: GraphQLString,
      resolve(parent) {
        return parent.last_name;
      },
    },

    email: {
      type: GraphQLString,
      resolve(parent) {
        return parent.email;
      },
    },

    memberships: {
      type: new GraphQLList(MembershipType),
      resolve(parent, args, ctx: Content) {
        return ctx.membershipsByUserId.load(parent.id);
      },
    },

    membershipsCount: {
      type: new GraphQLNonNull(GraphQLInt),
      resolve(parent, args, ctx: Context) {
        return ctx.userMembershipsCount.load(parent.id);
      },
    },
  },
});

export default UserType;

答案 3 :(得分:2)

通过设置管道过滤器,可以通过以下方式更加优雅地修改/删除标题:

const req = request.get(url);
req.pipefilter = function(response, dest) {
  // remove headers
  for(const h in response.headers) {
    dest.removeHeader(h);
  }
  // or modify
  dest.setHeader('Content-Type', 'text/html')
}
req.pipe(resp)