Node.js:分块传输编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6233562/
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
Node.js: chunked transfer encoding
提问by Gert Cuykens
Is that code valid HTTP/1.1?
该代码是否有效 HTTP/1.1?
var fs = require('fs')
var http = require('http')
var buf=function(res,fd,i,s,buffer){
if(i+buffer.length<s){
fs.read(fd,buffer,0,buffer.length,i,function(e,l,b){
res.write(b.slice(0,l))
//console.log(b.toString('utf8',0,l))
i=i+buffer.length
buf(res,fd,i,s,buffer)
})
}
else{
fs.read(fd,buffer,0,buffer.length,i,function(e,l,b){
res.end(b.slice(0,l))
fs.close(fd)
})
}
}
var app = function(req,res){
var head={'Content-Type':'text/html; charset=UTF-8'}
switch(req.url.slice(-3)){
case '.js':head={'Content-Type':'text/javascript'};break;
case 'css':head={'Content-Type':'text/css'};break;
case 'png':head={'Content-Type':'image/png'};break;
case 'ico':head={'Content-Type':'image/x-icon'};break;
case 'ogg':head={'Content-Type':'audio/ogg'};break;
case 'ebm':head={'Content-Type':'video/webm'};break;
}
head['Transfer-Encoding']='chunked'
res.writeHead(200,head)
fs.open('.'+req.url,'r',function(err,fd){
fs.fstat(fd,function(err, stats){
console.log('.'+req.url+' '+stats.size+' '+head['Content-Type']+' '+head['Transfer-Encoding'])
var buffer = new Buffer(100)
buf(res,fd,0,stats.size,buffer)
})
})
}
http.createServer(app).listen(8000,"127.0.0.1")
console.log('GET http://127.0.0.1:8000/appwsgi/www/index.htm')
I think I am violating HTTP/1.1 here? Text files do seem to work fine, but that could be coincidental. Is my header "200 OK" or need it to be "100"? Is one header sufficient?
我想我在这里违反了 HTTP/1.1?文本文件似乎工作正常,但这可能是巧合。我的标题是“200 OK”还是需要它是“100”?一个头就够了吗?
回答by onteria_
If you're doing chunked transfer encoding, you actually need to set that header:
如果您正在进行分块传输编码,则实际上需要设置该标头:
Transfer-Encoding: chunked
Transfer-Encoding: chunked
You can see from the headers returned by google, which does chunked transfers for the homepage and most likely other pages:
您可以从 google 返回的标题中看到,它为主页和最有可能的其他页面进行分块传输:
HTTP/1.1 200 OK
Date: Sat, 04 Jun 2011 00:04:08 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: PREF=ID=f9c65f4927515ce7:FF=0:TM=1307145848:LM=1307145848:S=fB58RFtpI5YeXdU9; expires=Mon, 03-Jun-2013 00:04:08 GMT; path=/; domain=.google.com
Set-Cookie: NID=47=UiPfl5ew2vCEte9JyBRkrFk4EhRQqy4dRuzG5Y-xeE---Q8AVvPDQq46GYbCy9VnOA8n7vxR8ETEAxKCh-b58r7elfURfiskmrOCgU706msiUx8L9qBpw-3OTPsY-6tl; expires=Sun, 04-Dec-2011 00:04:08 GMT; path=/; domain=.google.com; HttpOnly
Server: gws
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked
EDITYikes, that read is way too complicated:
编辑哎呀,阅读太复杂了:
var app = function(req,res){
var head={'Content-Type':'text/html'}
switch(req.url.slice(-3)){
case '.js':head={'Content-Type':'text/javascript'};break;
case 'css':head={'Content-Type':'text/css'};break;
case 'png':head={'Content-Type':'image/png'};break;
case 'ico':head={'Content-Type':'image/x-icon'};break;
case 'ogg':head={'Content-Type':'audio/ogg'};break;
case 'ebm':head={'Content-Type':'video/webm'};break;
}
res.writeHead(200,head)
var file_stream = fs.createReadStream('.'+req.url);
file_stream.on("error", function(exception) {
console.error("Error reading file: ", exception);
});
file_stream.on("data", function(data) {
res.write(data);
});
file_stream.on("close", function() {
res.end();
});
}
There you go, a nice streamed buffer for you to write with. Here's a blog post I wrote on different ways to read in files. I recommend looking that over so you can see how to best work with files in node's asynchronous environment.
好了,一个不错的流式缓冲区供您编写。这是我写的一篇关于读取文件的不同方式的博客文章。我建议查看一下,以便您可以了解如何在 node 的异步环境中最好地处理文件。
回答by Eye
Since Node.js implicitly sets 'Transfer-Encoding: chunked', all I needed to send in headers was the content type with charset like:
由于 Node.js 隐式设置了 ' Transfer-Encoding: chunked',所以我需要在标头中发送的是带有字符集的内容类型,例如:
'Content-Type': 'text/html; charset=UTF-8'
Initially it was:
最初是这样的:
'Content-Type': 'text/html'
... which didn't work. Specifying "charset=UTF-8" immediately forced Chrome to render chunked responses.
......这没有用。指定“ charset=UTF-8”会立即强制 Chrome 呈现分块响应。
回答by TooTallNate
Why are you doing all the fsoperations manually? You'd probably be better off using the fs.createReadStream()function.
你为什么要fs手动完成所有操作?您最好使用该fs.createReadStream()功能。
On top of that, my guess is that Chrome is expecting you to return a 206response code. Check req.headers.range, and see if Chrome is expecting a "range" of the media file to be returned. If it is, then you will have to only send back the portion of the file requested by the web browser.
最重要的是,我的猜测是 Chrome 期望您返回206响应代码。检查req.headers.range,看看 Chrome 是否期望返回媒体文件的“范围”。如果是,那么您将只需要发回 Web 浏览器请求的文件部分。
By why reinvent the wheel? There's tons of node modules that do this sort of thing for you. Try Connect/Express' staticmiddleware. Good luck!
为什么要重新发明轮子?有大量的节点模块可以为你做这种事情。试试 Connect/Express 的static中间件。祝你好运!

