为什么我不能删除节点代理中的transfer-encoding头?

时间:2014-10-27 12:36:13

标签: node.js middleware http-proxy

我有一个Node http代理服务器做一些响应正文重写,基本上这样做:

  1. 客户端GET localhost:8000 / api / items
  2. 节点代理发送localhost:8000 - > to example.com/api
  3. 服务器以json [{ id: 1234, url: http://example.com/api/items/1234 }]
  4. 响应
  5. 节点代理将json重写为[{ id: 1234, url: http://localhost:8000/api/items/1234 }]
  6. 节点代理计算新的content-length标头,设置它,并将响应返回给客户端
  7. 在后端服务器启用压缩之前,此工作正常。所以现在,默认情况下,响应被gzip压缩。我通过在我的代理中设置它来解决这个问题:

    req.headers['accept-encoding'] = 'deflate';

    所以在那之后,回复没有被gzip压缩,我可以解析它们并在必要时重写身体。但是,这停止了与IE合作。我认为问题是响应仍然有一个transfer-encoding=chunked标头,所以IE期望一个分块响应。因为存在transfer-encoding标头,所以没有content-length标头,即使我明确地设置它(这两个标头是互斥的)。我已经尝试了一切我能想到的删除transfer-encoding标头并取而代之的content-length标头,但没有任何效果。我已经尝试了所有这些:

    // In the context of my middleware response.writeHead function
    res.setHeader('transfer-encoding', null);
    res.setHeader('transfer-encoding', '');
    res.removeHeader('transfer-encoding');
    res.setHeader('content-length', modifiedBuffer.length); // this line alone worked before
    res.originalWriteHead.call(res, statusCode, { 'Content-Length', modifiedBuffer.length });
    
    // In the context of my middleware response.write function res.write(data, encoding)
    // Here, encoding parameter is undefined
    // According to docs, encoding defaults to utf8, could be 'chunked'
    res.oldWrite.call(res, modifiedBuffer, 'utf8');
    res.oldWrite.call(res, modifiedBuffer, '');
    res.oldWrite.call(res, modifiedBuffer, null);
    // tried all three previous the same for res.end
    

    基本上,无论我做什么,响应都不会被分块,但设置了transfer-encoding标头,而不是content-length。 Firefox,safari,chrome似乎都处理得很好,但是IE失败并出现错误XMLHttpRequest: Network Error 0x800c0007, No data is available for the requested resource.。这是(据我所知),因为它正在等待块(由于transfer-encoding标题),但得到了响应的结束,并且没有内容长度到读它。

    有谁知道如何解决这个问题?我是否在尝试删除transfer-encoding标题时采用了content-length

1 个答案:

答案 0 :(得分:0)

我自己想出来了:

我实际上正在使用两个中间件组件(我自己,在问题中描述)和express.js压缩。我的中间件正在解压缩响应,但压缩确保响应总是用transfer-encoding=chunked写入,content-length被删除。

删除express.js压缩模块为我解决了这个问题。