【问题标题】:Nodejs: convert string to bufferNodejs:将字符串转换为缓冲区
【发布时间】:2011-08-17 14:34:25
【问题描述】:

我正在尝试将字符串写入套接字(套接字称为“响应”)。这是我到目前为止的代码(我正在尝试实现字节缓存代理......):

var http = require('http');
var sys=require('sys');

var localHash={};

http.createServer(function(request, response) {
    var proxy = http.createClient(80, request.headers['host'])
    var proxy_request = proxy.request(request.method, request.url, request.headers);
    proxy_request.addListener('response', function (proxy_response) {
    proxy_response.addListener('data', function(x) {
        var responseData=x.toString();
        var f=50;
        var toTransmit="";
        var p=0;        

        var N=responseData.length;
        if(N>f){
            p=Math.floor(N/f);

            var hash="";
            var chunk="";
            for(var i=0;i<p;i++){
                chunk=responseData.substr(f*i,f);
                hash=DJBHash(chunk);
                if(localHash[hash]==undefined){
                    localHash[hash]=chunk;
                    toTransmit=toTransmit+chunk;
                }else{
                    sys.puts("***hit"+chunk);
                    toTransmit=toTransmit+chunk;//"***EOH"+hash;
                }
            }
            //remainder:
            chunk=responseData.substr(f*p);
            hash=DJBHash(chunk);
            if(localHash[hash]==undefined){
                localHash[hash]=chunk;
                toTransmit=toTransmit+chunk;
            }else{
                toTransmit=toTransmit+chunk;//"***EOH"+hash;
            }
        }else{
            toTransmit=responseData;
        }
        response.write(new Buffer(toTransmit));   /*error occurs here */
    });
    proxy_response.addListener('end', function() {
        response.end();
    });
    response.writeHead(proxy_response.statusCode, proxy_response.headers);
    });
    request.addListener('data', function(chunk) {
        sys.puts(chunk);
        proxy_request.write(chunk, 'binary');
    });
    request.addListener('end', function() {
        proxy_request.end();
    });
}).listen(8080);



function DJBHash(str) {
    var hash = 5381;
    for(var i = 0; i < str.length; i++) {
        hash = (((hash << 5) + hash) + str.charCodeAt(i)) & 0xffffffff;
    }
    if(hash<-1){
        hash=hash*-1;
    }
    return hash;
}

问题是,我在 Firefox 中不断收到“内容编码错误”。就好像 gizipped 的内容没有被正确传输。我已通过 console.log(x) 和 console.log(toTransmit) 确保“toTransmit”与“x”相同。

值得注意的是,如果我将response.write(new Buffer(toTransmit)) 替换为简单的response.write(x),代理会按预期工作,但我需要进行一些有效负载分析,然后传递“toTransmit”,而不是“x”。

我也尝试过response.write(toTransmit)(即没有转换为缓冲区)并且我不断收到相同的内容编码错误。

我真的被困住了。我以为我通过将字符串转换为另一个线程(http://stackoverflow.com/questions/7090510/nodejs-content-encoding-error)的缓冲区解决了这个问题,但我重新打开了一个新线程讨论我遇到的这个新问题。

我应该补充一点,如果我通过 Opera 中的代理打开一个页面,我会得到 gobblydeegook - 就好像 gzip 压缩的数据被损坏了一样。

非常感谢任何见解。

非常感谢,

【问题讨论】:

  • Buffer.byteLength

标签: javascript string encoding node.js


【解决方案1】:

这个怎么样?

var responseData = Buffer.from(x, 'utf8');

来自:Convert string to buffer Node

【讨论】:

  • 这是不弃用功能的正确方法
【解决方案2】:

如果不深入挖掘您的代码,在我看来您可能想要更改

var responseData=x.toString();

var responseData=x.toString("binary");

最后

response.write(new Buffer(toTransmit, "binary"));

【讨论】:

  • “二进制”编码通常是个坏主意。
  • @Andris:传奇,这就是我所做的:var responseData=x.toString("binary");response.write(toTransmit,"binary"); 现在一切正常!非常感谢您为我指明了正确的方向!!!
  • @Eamorr,说真的,不要那样做! “二进制”编码已弃用,将从节点中删除!我引用了文档:“'binary' - 一种仅使用每个字符的前 8 位将原始二进制数据编码为字符串的方法。这种编码方法已被弃用,应尽可能避免使用 Buffer 对象。这种编码将在以后的 Node 版本中被删除。”
  • @Eamorr,你能用你现在使用的代码更新你原来的帖子吗?
  • 'binary' 到现在已经有好几年了,它似乎不会去任何地方。甚至几个 node.js 核心 api 默认返回 'binary'。
【解决方案3】:

From the docs:

Pure Javascript 对 Unicode 友好,但对二进制数据不友好。什么时候 处理 TCP 流或文件系统,有必要处理 八位字节流。 Node 有几种用于操作、创建、 并消耗八位字节流。

原始数据存储在 Buffer 类的实例中。缓冲区是 类似于整数数组,但对应于原始内存 V8 堆外的分配。缓冲区无法调整大小。

所以,不要使用字符串来处理二进制数据。

proxy_request.write(chunk, 'binary'); 更改为proxy_request.write(chunk);

省略var responseData=x.toString();,这是个坏主意。

不要在字符串上使用substr,而是在缓冲区上使用slice

不要使用字符串执行+,而是使用buffertools 中的“concat”方法。

【讨论】:

    【解决方案4】:

    实际上,现在 new Buffer() 在 node.js v10+ 中已被弃用,所以更好用 缓冲区.from(,) 来自

     response.write(new Buffer(toTransmit));
    

     response.write(Buffer.from(toTransmit,'binary'));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 2016-09-23
      • 1970-01-01
      • 2023-03-02
      • 1970-01-01
      • 2019-07-30
      相关资源
      最近更新 更多