简单的Nodejs Web服务器总是发送文本/普通的css和js文件

Nodejs创build一个简单的Web服务器时,我Nodejs了一个奇怪的问题。 http服务器正常运行,并接受请求和响应。 但是,由于某种原因,它总是希望发送一种content-type:text/plain 。 例如.js.css文件总是以text/plain而通常应该以text/cssapplication/javascriptforms发送。 Chrome浏览器,我用来testing这个,总是抱怨资源的MIMEtypes:

Resource interpreted as Stylesheet but transferred with MIME type text/plain: "http://localhost:3000/test.css".

Resource interpreted as Script but transferred with MIME type text/plain: "http://localhost:3000/test-client.js".

这最终意味着什么是从未应用到页面的css 。 我已经添加了一些日志logging,看起来http响应正在发送正确的MIMEtypes。

我创build了一个我正在做的准系统版本。 希望有人能指出我编写的缺陷:

test.js

 var http = require('http'), fs = require('fs'), url = require('url'), path = require('path'); var contentTypes = { '.html': 'text/html', '.css': "text/css", '.js': 'application/javascript' }; http.createServer(function(request, response) { // get file based on pathname var uri = url.parse(request.url).pathname, filename = path.join(__dirname, uri); fs.exists(filename, function(exists) { // if root directory, append test.html if (fs.statSync(filename).isDirectory()) { filename += 'test.html'; } // figure out MIME type by file ext var contentType = contentTypes[path.extname(filename)]; fs.readFile(filename, function(err, file) { // errors? if (err) { response.writeHead(404, {'Content-type:': 'text/plain'}); response.write(err + "\n"); response.end(); } else { console.log('MIME TYPE for: ', filename , contentType); response.setHeader('Content-Type:', contentType); response.writeHead(200); response.write(file); response.end(); } }); }); }).listen(3000, function(){ console.log("server started and listening on port 3000"); }); 

的test.html

 <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="test.css" type="text/css" /> </head> <body> <h1>Test</h1> <div id="test"></div> <script type="text/javascript" src="test-client.js"></script> </body> </html> 

test.css

 h1 { color: red; } 

testingclient.js

 var div = document.getElementById('test'); div.innerHTML = 'test client ran successfully'; 

我认为这个问题是,你正在使用一个不必要的:Content-Type之后设置标题。 你应该做response.setHeader('Content-Type',contentType); 或者,我认为更好,这样做: response.writeHead(200,{'Content-Type':contentType});

而且你必须使fs.readFile被一个闭包封装,否则某些文件(特别是最后一个文件)将被多次读取,而其他文件将不会被读取。 contentType不会像你所希望的那样被设置。 这是因为fs.readFile使用的callback策略。 当html文件只加载一个外部文件时,不会出现这个问题,但是当外部文件(css,js,png)加载多个文件时,会出现上面指出的情况。 (我不能用我的Gmaillogin,所以我作为一个客人发布)

所以你的代码应该做一些改变,如下所示:

 ;(function (filename, contentType) { fs.readFile(filename, function(err, file) { // do the left stuff here }); }(filename, contentType));