终极目标:掌握和使用node
本博客目的:记录node学习的进度和心得
内容:Nodejs中的利用HTTP模块 URl模块 PATH模块 FS模块创建一个WEB服务器。
WEB服务器
Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。
目前最主流的三个Web服务器是Apache Nginx IIS。
Nodejs创建一个WEB服务器
可以用nodejs提供一个WEB服务器。
最初,我们会放置静态文件到服务器,有图片,css,JS,HTML等。然后当客户端发送请求,服务器需要解析请求URL,找到正确的资源位置,然后以一定形式返回。

例子1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| var http=require('http');
var fs=require('fs'); http.createServer(function(req,res){
var pathname=req.url; if(pathname=='/'){ pathname='/index.html'; }
if(pathname!='/favicon.ico'){ console.log(pathname); fs.readFile('static/'+pathname,function(err,data){
if(err){
console.log('404');
}else{ res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"}); res.write(data); res.end(); }
})
}
}).listen(8001);
|
在VSCODE运行这段代码,然后打开浏览器,对应URL即可完成本地服务器对文件或网页的访问。

但我们从F12浏览器控制台发现,我们请求这个index.html文件的时候,这个HTML加载请求了很多CSS文件和JS文件,但发现其并没有加载在页面上展示。

原因在于:当我们CSS文件的响应头,发现其是content type是text/html,内容解析为text/html。所以我们应该在源代码上对不同的文件,修改对应不同的响应头。

例子2:
如果页面404,可以转入到自定义显示404的404.html文件上。
根据不同后缀名,返回不同的content type的响应头。这里,除了可以使用原生JS,通常使用node内置的path模块。(例如后缀名就是path.extname(“XXX.CSS”))
我们可以先定义一个后缀名处理的模块。

在代码引入之前后缀名处理模块,和修改相关代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
var http=require('http');
var fs=require('fs');
var path=require('path');
var mimeModel=require('./model/getmime.js');
http.createServer(function(req,res){
var pathname=req.url; if(pathname=='/'){ pathname='/index.html'; }
var extname=path.extname(pathname);
if(pathname!='/favicon.ico'){
fs.readFile('static/'+pathname,function(err,data){
if(err){
console.log('404');
fs.readFile('static/404.html',function(error,data404){ if(error){ console.log(error); } res.writeHead(404,{"Content-Type":"text/html;charset='utf-8'"}); res.write(data404); res.end(); })
}else{
var mime=mimeModel.getMime(extname); res.writeHead(200,{"Content-Type":""+mime+";charset='utf-8'"}); res.write(data); res.end(); }
})
}
}).listen(8001);
|
然后运行。
此时,CSS,js文件都正确加载了:

因为不同文件的响应头写正确了:

但仍然存在一些问题:

我们之前使用的是var pathname=req.url;
。


所以,一些JSON的get传值没有找到,这个时候需要使用URL模块及其相关方法,正确找到pathname。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
var http=require('http');
var fs=require('fs');
var path=require('path');
var url=require('url');
var mimeModel=require('./model/getmime.js');
http.createServer(function(req,res){
var pathname=url.parse(req.url).pathname;
console.log(pathname);
if(pathname=='/'){ pathname='/index.html'; }
var extname=path.extname(pathname);
if(pathname!='/favicon.ico'){
fs.readFile('static/'+pathname,function(err,data){
if(err){
console.log('404');
fs.readFile('static/404.html',function(error,data404){ if(error){ console.log(error); } res.writeHead(404,{"Content-Type":"text/html;charset='utf-8'"}); res.write(data404); res.end(); })
}else{
var mime=mimeModel.getMime(extname); res.writeHead(200,{"Content-Type":""+mime+";charset='utf-8'"}); res.write(data); res.end(); }
})
}
}).listen(8001);
|
此时,一些JSON数据也正确加载往网页了:

JSON文件也响应成功:

小结:这样就完成了一个最基本的静态服务器功能。
但是,仍然存在一些问题:
例如图片文件,响应头返回text/html:

实际上,我们会写一个
控制所有文件格式对应的content type:

类似地,重新写一个读取后缀名的方法模块:
注意如果使用fs.readFile是一个异步读取文件的方式,可能导致请求时读取不到数据,显示undefined。
所以应该使用同步的方法fs.readFileSync:

然后在使用的地方引入使用:

最后就可以得到CSS(任意文件)对应的content type(text/css)。
因此,最后只需在源代码基础上修改获取扩展名方法的模块及对应方法:

运行

此时,对应文件的content type正确按照我们JSON文件对应上了。
小结:这样就使用nodejs创建了一个类似Apache Nginx IIS的WEB服务器。
最后的完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
var http=require('http');
var fs=require('fs');
var path=require('path');
var url=require('url');
var mimeModel=require('./model/getmimefromfile.js');
http.createServer(function(req,res){
var pathname=url.parse(req.url).pathname;
console.log(pathname);
if(pathname=='/'){ pathname='/index.html'; }
var extname=path.extname(pathname);
if(pathname!='/favicon.ico'){
fs.readFile('static/'+pathname,function(err,data){
if(err){
console.log('404');
fs.readFile('static/404.html',function(error,data404){ if(error){ console.log(error); } res.writeHead(404,{"Content-Type":"text/html;charset='utf-8'"}); res.write(data404); res.end(); })
}else{
var mime=mimeModel.getMime(fs,extname); res.writeHead(200,{"Content-Type":""+mime+";charset='utf-8'"}); res.write(data); res.end(); } })
}
}).listen(8002);
|