Javascript Nodejs:将字符串转换为缓冲区
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7094615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Nodejs: convert string to buffer
提问by Eamorr
I'm trying to write a string to a socket (socket is called "response"). Here is the code I have sofar (I'm trying to implement a byte caching proxy...):
我正在尝试将字符串写入套接字(套接字称为“响应”)。这是我迄今为止的代码(我正在尝试实现字节缓存代理...):
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;
}
The trouble is, I keep getting a "content encoding error" in Firefox. It's as if the gizipped content isn't being transmitted properly. I've ensured that "toTransmit" is the same as "x" via console.log(x) and console.log(toTransmit).
问题是,我在 Firefox 中不断收到“内容编码错误”。就好像压缩后的内容没有被正确传输。我已经通过 console.log(x) 和 console.log(toTransmit) 确保“toTransmit”与“x”相同。
It's worth noting that if I replace response.write(new Buffer(toTransmit))
with simply response.write(x)
, the proxy works as expected, but I need to do some payload analysis and then pass "toTransmit", not "x".
值得注意的是,如果我response.write(new Buffer(toTransmit))
简单地替换为response.write(x)
,代理会按预期工作,但我需要做一些有效负载分析,然后传递“toTransmit”,而不是“x”。
I've also tried to response.write(toTransmit)
(i.e. without the conversion to buffer) and I keep getting the same content encoding error.
我也尝试过response.write(toTransmit)
(即没有转换为缓冲区)并且我不断收到相同的内容编码错误。
I'm really stuck. I thought I had this problem fixed by converting the string to a buffer as per another thread (http://stackoverflow.com/questions/7090510/nodejs-content-encoding-error), but I've re-opened a new thread to discuss this new problem I'm experiencing.
我真的被困住了。我以为我通过根据另一个线程(http://stackoverflow.com/questions/7090510/nodejs-content-encoding-error)将字符串转换为缓冲区来解决这个问题,但我重新打开了一个新线程讨论我遇到的这个新问题。
I should add that if I open a page via the proxy in Opera, I get gobblydeegook - it's as if the gzipped data gets corrupted.
我应该补充一点,如果我通过 Opera 中的代理打开一个页面,我会收到 gobblydeegook - 就好像 gzipped 数据被损坏了一样。
Any insight greatly appreciated.
任何见解都非常感谢。
Many thanks in advance,
提前谢谢了,
回答by user1527225
How about this?
这个怎么样?
var responseData = Buffer.from(x, 'utf8');
from: Convert string to buffer Node
from:将字符串转换为缓冲区节点
回答by Andris
Without digging very deep into your code, it seems to me that you might want to change
没有深入研究你的代码,在我看来你可能想要改变
var responseData=x.toString();
to
到
var responseData=x.toString("binary");
and finally
最后
response.write(new Buffer(toTransmit, "binary"));
回答by thejh
从文档:
Pure Javascript is Unicode friendly but not nice to binary data. When dealing with TCP streams or the file system, it's necessary to handle octet streams. Node has several strategies for manipulating, creating, and consuming octet streams.
Raw data is stored in instances of the Buffer class. A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized.
纯 Javascript 对 Unicode 友好,但对二进制数据不友好。在处理 TCP 流或文件系统时,有必要处理八位字节流。Node 有多种策略来操作、创建和使用八位字节流。
原始数据存储在 Buffer 类的实例中。Buffer 类似于整数数组,但对应于 V8 堆外的原始内存分配。缓冲区不能调整大小。
So, don't use strings for handling binary data.
所以,不要使用字符串来处理二进制数据。
Change proxy_request.write(chunk, 'binary');
to proxy_request.write(chunk);
.
更改proxy_request.write(chunk, 'binary');
为proxy_request.write(chunk);
。
Omit var responseData=x.toString();
, that's a bad idea.
省略var responseData=x.toString();
,这是个坏主意。
Instead of doing substr
on a string, use slice
on a buffer.
不要substr
在字符串上使用slice
,而是在缓冲区上使用。
Instead of doing +
with strings, use the "concat" method from the buffertools.
不要+
使用字符串,而是使用buffertools 中的“concat”方法。