2011-06-03 12 views
8

क्या यह कोड मान्य 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') 

मुझे लगता है कि मैं यहां HTTP/1.1 का उल्लंघन कर रहा हूं? टेक्स्ट फाइलें ठीक काम करने लगती हैं, लेकिन यह संयोग हो सकता है। क्या मेरा हेडर "200 ओके" है या इसे "100" होना चाहिए? क्या एक हेडर पर्याप्त है?

उत्तर

11

आप chunked स्थानांतरण एन्कोडिंग कर रहे हैं, तो आप वास्तव में उस हेडर निर्धारित करने की आवश्यकता:

Transfer-Encoding: chunked

आप गूगल द्वारा वापस हेडर, जो होमपेज पर और सबसे अधिक संभावना के लिए स्थानान्तरण chunked है से देख सकते हैं अन्य पन्नों:

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 

संपादित ओह, कि पढ़ने रास्ता बहुत ही जटिल है:

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(); 
}); 
} 

वहां आप लिखने के लिए एक अच्छा स्ट्रीम किया गया बफर जाते हैं। यहां एक ब्लॉग पोस्ट है जिसे मैंने फाइलों में पढ़ने के विभिन्न तरीकों पर लिखा था। मैं इसे देखने की अनुशंसा करता हूं ताकि आप देख सकें कि नोड के असीमित वातावरण में फ़ाइलों के साथ सबसे अच्छा कैसे काम करना है।

+0

यह भ्रमित है क्योंकि प्रतिक्रिया को 200 होने की आवश्यकता होती है जब खंडित पैकेज भेजे जा रहे हैं? –

+0

@Gert Google की ओर से हेडर्स को पढ़ें, मैंने अपनी प्रतिक्रिया में पोस्ट किया है जिसमें 200 ओके हैं। बेशक, अगर आप रीडायरेक्ट कर रहे हैं या किसी और के बाहर कुछ और हैं "हाँ मेरे पास यह फ़ाइल अभी है और इसे आपको भेजने जा रहा है" टाइप की स्थिति, आपको इसके बजाय उचित शीर्षलेख का उपयोग करना चाहिए। मैं सभी शीर्षकों पर एक नज़र डालने की सलाह देता हूं और वे किसके लिए खड़े हैं: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html। यदि आप निम्न स्तर पर node.js का उपयोग करना जारी रखना चाहते हैं तो यह आपके लिए फायदेमंद होगा। स्पष्ट कोडसेट के साथ –

3

आप सभी fs संचालन मैन्युअल रूप से क्यों कर रहे हैं? आप शायद fs.createReadStream() फ़ंक्शन का उपयोग करके बेहतर हो जाएंगे।

उस पर, मेरा अनुमान है कि क्रोम आपको 206 प्रतिक्रिया कोड वापस करने की उम्मीद कर रहा है। req.headers.range देखें, और देखें कि क्या क्रोम मीडिया फ़ाइल की "रेंज" को वापस करने की अपेक्षा कर रहा है या नहीं। यदि ऐसा है, तो आपको केवल वेब ब्राउज़र द्वारा अनुरोध की गई फ़ाइल का हिस्सा वापस भेजना होगा।

क्यों पहिया को फिर से शुरू करें? नोड मॉड्यूल के बहुत सारे हैं जो आपके लिए इस तरह की चीज करते हैं। कनेक्ट/एक्सप्रेस 'static मिडलवेयर आज़माएं। सौभाग्य!

+1

कोड को ठीक करने के बाद, यह केवल एक बार मीडिया चलाता है। मुझे लगता है कि आप रेंज प्रतिक्रिया के बारे में सही हैं। –

9

के बाद से Node.js परोक्ष सेट 'स्थानांतरण-एन्कोडिंग: chunked', सब मैं हेडर में भेजने के लिए जरूरत के साथ सामग्री प्रकार था चारसेट की तरह:

'Content-Type': 'text/html; charset=UTF-8' 

शुरू में यह था:

'Content-Type': 'text/html' 

... जो काम नहीं करता था। निर्दिष्ट करना "वर्णसेट = यूटीएफ -8" तुरंत क्रोम को चकित प्रतिक्रिया प्रस्तुत करने के लिए मजबूर किया।

+1

मेरे कोड ने काम किया, लेकिन मैंने देखा कि यह टेक्स्ट/सादा सामग्री-प्रकार (क्रोम पर परीक्षण) के साथ काम नहीं करता है ... अजीब व्यवहार ... –

+0

मुझे इस बात का पूरा यकीन नहीं है कि आपको यह व्यवहार क्यों मिला है। मैं इसका परीक्षण करूंगा और बाद में जवाब दूंगा। – Eye

+0

मेरे परीक्षणों में यह फ़ायरफ़ॉक्स पर काम करता है, लेकिन क्रोम पर नहीं (केवल टेक्स्ट/सादा सामग्री-प्रकार के लिए) ... –

संबंधित मुद्दे