Node.js:分块传输编码
该代码是否有效HTTP/1.1Node.js:分块传输编码,node.js,Node.js,该代码是否有效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,
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')
var fs=require('fs'))
var http=require('http')
var buf=函数(res、fd、i、s、缓冲器){
如果(i+buffer.length为什么要手动执行所有的fs
操作?您最好使用fs.createReadStream()
函数
最重要的是,我猜Chrome希望您返回206
响应代码。检查req.headers.range
,看看Chrome是否希望返回媒体文件的“range”。如果是,那么您只需返回web浏览器请求的部分文件
为什么要重新发明轮子?有很多节点模块可以为您完成这类工作。请尝试Connect/Express'static
中间件。祝您好运!如果您正在进行分块传输编码,您实际上需要设置该标头:
传输编码:分块
你可以从谷歌返回的标题中看到,谷歌对主页和其他页面进行分块传输:
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
编辑Yikes,读起来太复杂了:
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();
});
}
好了,一个很好的流式缓冲区供您使用。这是我写的一篇关于读取文件的不同方式的博文。我建议您查看一下,这样您就可以看到如何在节点的异步环境中最好地处理文件。由于node.js隐式设置了“传输编码:chunked”,所以我只需要发送头具有字符集的内容类型是否类似于:
'Content-Type': 'text/html; charset=UTF-8'
最初是:
'Content-Type': 'text/html'
…无效。指定“字符集=UTF-8”立即强制Chrome呈现分块响应。这令人困惑,因为发送分块包时,响应是否需要为200?@Gert读取我在响应中发布的标题,标题中有200 OK。当然,如果你正在重定向,或者是某个应用程序之外的其他内容“是的,我现在就有这个文件,我会把它寄给你"键入“情况”,您应该使用相应的标题。我建议您查看所有标题及其代表的内容:。如果您希望继续像这样在较低级别上使用node.js,这将对您有益。修复代码后,它只播放媒体一次。我想您对范围响应的看法是正确的cit charset我的代码运行正常,但我注意到它不适用于文本/普通内容类型(在chrome上测试)…奇怪的行为…我不太确定你为什么会有这种行为。我将对此进行测试并稍后回复。在我的测试中,它适用于firefox,但不适用于chrome(仅适用于文本/普通内容类型)…@fra_casula我也遇到了同样的问题。这似乎是WebKit中的一个bug:有一个解决方法可以添加“X-Content-Type-Options:nosniff”标题。