Nodejs:将字符串转换为缓冲区

Eam*_*orr 13 javascript string encoding node.js

我正在尝试将字符串写入套接字(套接字称为"响应").这是我已经安装的代码(我正在尝试实现一个字节缓存代理......):

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;
}
Run Code Online (Sandbox Code Playgroud)

麻烦的是,我在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压缩数据一样.

任何见解都非常感激.

提前谢谢了,

use*_*225 26

这个怎么样?

var responseData= Buffer.from( x, 'utf8' )
Run Code Online (Sandbox Code Playgroud)

from:将字符串转换为缓冲区节点


And*_*ris 20

如果不深入研究代码,我觉得你可能想要改变

var responseData=x.toString();
Run Code Online (Sandbox Code Playgroud)

var responseData=x.toString("binary");
Run Code Online (Sandbox Code Playgroud)

最后

response.write(new Buffer(toTransmit, "binary"));
Run Code Online (Sandbox Code Playgroud)

  • @Eamorr,说真的,不要那样做!不推荐使用"二进制"编码,它将从节点中删除!我引用了文档:"'binary' - 一种通过仅使用每个字符的前8位将原始二进制数据编码为字符串的方法.这种编码方法已弃用,应尽可能避免使用Buffer对象.此编码将在未来的Node版本中删除." (3认同)
  • "二进制"编码通常是一个坏主意. (2认同)
  • 'binary' 到现在已经有好几年了,它似乎不会去任何地方。默认情况下,甚至几个 node.js 核心 api 都返回“二进制”。 (2认同)

the*_*ejh 5

来自文档:

纯Javascript是Unicode友好的,但对二进制数据不好.在处理TCP流或文件系统时,必须处理八位字节流.Node有几种操作,创建和使用八位字节流的策略.

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

因此,不要使用字符串来处理二进制数据.

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

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

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

而不是+使用字符串,使用buffertools中的"concat"方法.