Node.js:分块传输编码

Ger*_*ens 9 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,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')
Run Code Online (Sandbox Code Playgroud)

我想我在这里违反了HTTP/1.1?文本文件确实可以正常工作,但这可能是巧合.我的标题是"200 OK"还是需要它为"100"?一个标题是否足够?

ont*_*ia_ 12

如果您正在进行分块传输编码,您实际上需要设置该标头:

Transfer-Encoding: chunked

你可以从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
Run Code Online (Sandbox Code Playgroud)

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

你去,一个很好的流缓冲区供你写.这是我用不同的方式阅读文件的博客文章.我建议您查看它,以便了解如何在节点的异步环境中最好地处理文件.


Eye*_*Eye 10

由于Node.js隐式设置' Transfer-Encoding:chunked ',所以我需要在头文件中发送的内容类型是charset,如:

'Content-Type': 'text/html; charset=UTF-8'
Run Code Online (Sandbox Code Playgroud)

最初它是:

'Content-Type': 'text/html'
Run Code Online (Sandbox Code Playgroud)

......哪些不起作用.指定" charset = UTF-8 "会立即强制Chrome呈现分块响应.

  • 使用显式字符集我的代码工作,但我注意到它不适用于text/plain内容类型(在chrome上测试)...奇怪的行为...... (2认同)
  • @fra_casula我遇到了同样的问题.它似乎是WebKit中的一个错误:https://code.google.com/p/chromium/issues/detail?id = 156023有一种解决方法可以添加"X-Content-Type-Options:nosniff"标题. (2认同)