如何在解析Node中的响应之前更改/删除/忽略http标头



我目前正在使用Node从API (Discogs API)获取数据,并且在请求时出现此错误:

{ [Error: Parse Error] bytesParsed: 0, code: 'HPE_INVALID_CONSTANT' }

使用此链接:http://api.discogs.com/releases/249504(但当content-length != actual content length时,我对每个其他请求都有相同的错误)

和这个代码:

var http  = require('http');
var options = {
  hostname: 'api.discogs.com',
  port: 80,
  path: '/releases/249504',
  method: 'GET'
};
var req = http.request(options, function(res) {
  console.log("statusCode: ", res.statusCode);
  console.log("headers: ", res.headers);
  res.on('data', function(d) {
    console.log(d);
  });
});
req.end();
req.on('error', function(e) {
  console.error(e);
});

我发现Content-length值总是小于实际响应字节长度。

Content-length : 2142
Actual Byte Length : 7,734 Bytes (according to https://mothereff.in/byte-counter)

我读到Node的解析器非常严格,这就是为什么它解析响应失败的原因。

最后,我问您是否有一种方法可以在Node解析响应之前忽略/修改/删除Header,以便解析器可以通过忽略Content-Length来完成工作?

这与无效的内容长度无关,因为使用cURL:

也不起作用。
$ curl  http://api.discogs.com/releases/249504
curl: (52) Empty reply from server

显然API服务器要求设置一个用户代理头:

var options = {
  hostname : 'api.discogs.com',
  port     : 80,
  path     : '/releases/249504',
  method   : 'GET',
  headers  : { 'user-agent' : 'foo/1.0' }
};

内容长度的差异:2142为gzip压缩响应(content-encoding: gzip)的大小,7734为未压缩响应的大小。显然,您的字节计数器测试只请求未压缩的响应,但您检查报头的客户端正在请求压缩响应。

回到在解析Node中的响应之前更改头的主题,您可以通过在socket: "data"事件上用自己的函数替换标准处理程序轻松地完成。

https://github.com/nodejs/http2/blob/master/lib/_http_client.js L655

var req = http.request(options, function(res) {
  console.log("statusCode: ", res.statusCode);
  console.log("headers: ", res.headers); // without "Pragma: public" header
  res.on('data', function(d) {
    console.log(d);
  });
});
// catch socket object on conection initialization
req.on('socket', function (socket) {
    // https://nodejs.org/api/events.html
    var standardHandler = socket.listeners('data')[0];
    socket.off('data', standardHandler);
    socket.on('data', function(data) {
        var str = data.toString();
        console.log(str);
        // HTTP/1.x 200 OK
        // Date: Sat, 28 Nov 2009 04:36:25 GMT
        // Connection: close
        // Pragma: public
        // Expires: Sat, 28 Nov 2009 05:36:25 GMT
        // Cache-Control: max-age=3600, public
        // Content-Type: text/html; charset=UTF-8
        // Content-Length: 533424
        // Content-Encoding: gzip
        // Vary: Accept-Encoding, Cookie, User-Agent
        //  
        // <!DOCTYPE html PUBLIC "-//W3C//DTD
        // Do anything you need
        // removing 4 line
        var lines = str.split('rn');
        lines.splice(3, 1)
        str = lines.join('rn');
        // Now pass new data onto standard request handler
        standardHandler.call(socket, Buffer.from(str, "utf-8"));
    })
});
req.end();

相关内容

  • 没有找到相关文章

最新更新