一、建立简单的Web服务器涉及到Node.js的一些基本知识点:
1、请求模块
在Node.js中,系统提供了许多有用的模块(当然你也可以用JavaScript编写自己的模块,以后的章节我们将详细讲解),如http、url等。模块封装特定的功能,提供相应的方法或属性,要使用这些模块,需要先请求模块获得其操作对象。
例如要使用系统的http模块,可以这样写:
var libHttp = require('http'); //请求HTTP协议模块
这样,以后的程序将可以通过变量libHttp访问http模块的功能。本章例程中使用了以下系统模块:
http:封装http协议的服务器和客户端实现;
url:封装对url的解析和处理;
fs:封装对文件系统操作的功能;
path:封装对路径的解析功能。
有了这些模块,我们就可以站在巨人的肩膀上构建自己的应用。
2、控制台
为了更好的观察程序的运行,方便在异常时查看错误,可以通便变量console使用控制台的功能。
console.log('这是一段日志信息');
计时并在控制台上输出计时信息: //开始计时
console.timeEnd('计时器1'); //开始名称为“计时器1”的计时器 ...
...
... //结束计时,并输出到控制台
console.timeEnd('计时器1'); //结束称为“计时器1”的计时器并输出
3、定义函数
在Node.js中定义函数的办法与普通JavaScript中完全相同,不过我们推荐的写法如下,即使用一个变量为函数命名,这样可以比较方便明确的将函数作为参数传递给其他函数:
//定义一个名为showErr的函数
var showErr=function(msg){
var inf="错误!"+msg;
console.log(inf+msg);
return msg;
}
4、创建Web服务器并侦听访问请求
创建Web服务器最重要的是提供Web请求的响应函数,它有两个参数,第一个代表客户端请求的信息,另一个代表将要返回给客户端的信息。在响应函数中应解析请求信息,依据请求,组装返后内容。
//请求模块
var libHttp = require('http'); //HTTP协议模块 //Web服务器主函数,解析请求,返回Web内容
var funWebSvr = function (req, res){
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html><body>');
res.write('<h1>*** Node.js ***</h1>');
res.write('<h2>Hello!</h2>');
res.end('</body></html>');
} //创建一个http服务器
var webSvr=libHttp.createServer(funWebSvr); //开始侦听8124端口
webSvr.listen(8124);
对于简单的Web网页访问请求,重要的信息包含在请求信息参数的url里,我们可以使用url解析模块解析url中的访问路径,并利用path模块,将访问路径组装为要访问的实际文件路径用于返回。
var reqUrl=req.url; //获取请求的url //向控制台输出请求的路径
console.log(reqUrl); //使用url解析模块获取url中的路径名
var pathName = libUrl.parse(reqUrl).pathname; //使用path模块获取路径名中的扩展名
if (libPath.extname(pathName)=="") {
//如果路径没有扩展名
pathName+="/"; //指定访问目录
} if (pathName.charAt(pathName.length-1)=="/"){
//如果访问目录
pathName+="index.html"; //指定为默认网页
} //使用路径解析模块,组装实际文件路径
var filePath = libPath.join("./WebRoot",pathName);
由于是Web请求,需要在返回内容中包含http返回头,这里重点是依据要访问的文件路径的文件扩展名,设置http返回头的内容类型。
var contentType=""; //使用路径解析模块获取文件扩展名
var ext=libPath.extname(filePath); switch(ext){
case ".html":
contentType= "text/html";
break;
case ".js":
contentType="text/javascript";
break;
...
...
default:
contentType="application/octet-stream";
} //在返回头中写入内容类型
res.writeHead(200, {"Content-Type": contentType });
7、向返回对象中写入访问的文件内容
有了需要访问的文件实际路径,有了文件对应的内容类型,就可以利用fs文件系统模块读取文件流并返回给客户端。
//判断文件是否存在
libPath.exists(filePath,function(exists){
if(exists){//文件存在
//在返回头中写入内容类型
res.writeHead(200, {"Content-Type": funGetContentType(filePath) }); //创建只读流用于返回
var stream = libFs.createReadStream(filePath, {flags : "r", encoding : null}); //指定如果流读取错误,返回404错误
stream.on("error", function() {
res.writeHead(404);
res.end("<h1>404 Read Error</h1>");
}); //连接文件流和http返回流的管道,用于返回实际Web内容
stream.pipe(res);
}
else { //文件不存在 //返回404错误
res.writeHead(404, {"Content-Type": "text/html"});
res.end("<h1>404 Not Found</h1>");
}
});
1、完整源码
以下100行左右的JavaScript就是建立这样一个简单web服务器的全部源码:
1 //------------------------------------------------
2 //WebSvr.js
3 // 一个演示Web服务器
4 //------------------------------------------------
5
6 //开始服务启动计时器
7 console.time('[WebSvr][Start]');
8
9 //请求模块
10 var libHttp = require('http'); //HTTP协议模块
11 var libUrl=require('url'); //URL解析模块
12 var libFs = require("fs"); //文件系统模块
13 var libPath = require("path"); //路径解析模块
14
15 //依据路径获取返回内容类型字符串,用于http返回头
16 var funGetContentType=function(filePath){
17 var contentType="";
18
19 //使用路径解析模块获取文件扩展名
20 var ext=libPath.extname(filePath);
21
22 switch(ext){
23 case ".html":
24 contentType= "text/html";
25 break;
26 case ".js":
27 contentType="text/javascript";
28 break;
29 case ".css":
30 contentType="text/css";
31 break;
32 case ".gif":
33 contentType="image/gif";
34 break;
35 case ".jpg":
36 contentType="image/jpeg";
37 break;
38 case ".png":
39 contentType="image/png";
40 break;
41 case ".ico":
42 contentType="image/icon";
43 break;
44 default:
45 contentType="application/octet-stream";
46 }
47
48 return contentType; //返回内容类型字符串
49 }
50
51 //Web服务器主函数,解析请求,返回Web内容
52 var funWebSvr = function (req, res){
53 var reqUrl=req.url; //获取请求的url
54
55 //向控制台输出请求的路径
56 console.log(reqUrl);
57
58 //使用url解析模块获取url中的路径名
59 var pathName = libUrl.parse(reqUrl).pathname;
60
61 if (libPath.extname(pathName)=="") {
62 //如果路径没有扩展名
63 pathName+="/"; //指定访问目录
64 }
65
66 if (pathName.charAt(pathName.length-1)=="/"){
67 //如果访问目录
68 pathName+="index.html"; //指定为默认网页
69 }
70
71 //使用路径解析模块,组装实际文件路径
72 var filePath = libPath.join("./WebRoot",pathName);
73
74 //判断文件是否存在
75 libPath.exists(filePath,function(exists){
76 if(exists){//文件存在
77 //在返回头中写入内容类型
78 res.writeHead(200, {"Content-Type": funGetContentType(filePath) });
79
80 //创建只读流用于返回
81 var stream = libFs.createReadStream(filePath, {flags : "r", encoding : null});
82
83 //指定如果流读取错误,返回404错误
84 stream.on("error", function() {
85 res.writeHead(404);
86 res.end("<h1>404 Read Error</h1>");
87 });
88
89 //连接文件流和http返回流的管道,用于返回实际Web内容
90 stream.pipe(res);
91 }
92 else { //文件不存在
93
94 //返回404错误
95 res.writeHead(404, {"Content-Type": "text/html"});
96 res.end("<h1>404 Not Found</h1>");
97 }
98 });
99
100
101
102 }
103
104 //创建一个http服务器
105 var webSvr=libHttp.createServer(funWebSvr);
106
107 //指定服务器错误事件响应
108 webSvr.on("error", function(error) {
109 console.log(error); //在控制台中输出错误信息
110 });
111
112
113 //开始侦听8124端口
114 webSvr.listen(8124,function(){
115
116 //向控制台输出服务启动的信息
117 console.log('[WebSvr][Start] running at http://127.0.0.1:8124/');
118
119 //结束服务启动计时器并输出
120 console.timeEnd('[WebSvr][Start]');
学习用node.js建立一个简单的web服务器的更多相关文章
-
学习用Node.js和Elasticsearch构建搜索引擎(6):实际项目中常用命令使用记录
1.检测集群是否健康. curl -XGET 'localhost:9200/_cat/health?v' #后面加一个v表示让输出内容表格显示表头 绿色表示一切正常,黄色表示所有的数据可用但是部分副 ...
-
自己动手模拟开发一个简单的Web服务器
开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...
-
利用 nodeJS 搭建一个简单的Web服务器(转)
下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...
-
如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1
原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...
-
自己模拟的一个简单的web服务器
首先我为大家推荐一本书:How Tomcat Works.这本书讲的很详细的,虽然实际开发中我们并不会自己去写一个tomcat,但是对于了解Tomcat是如何工作的还是很有必要的. Servlet容器 ...
-
一个简单的Web服务器-支持Servlet请求
上接 一个简单的Web服务器-支持静态资源请求,这个服务器可以处理静态资源的请求,那么如何处理Servlet请求的呢? 判断是否是Servlet请求 首先Web服务器需要判断当前请求是否是Servle ...
-
一个简单的Web服务器-支持静态资源请求
目标 实现一个简单的Web服务器,能够根据HTTP请求的URL响应对应的静态资源,如果静态资源不存在则响应404. HttpServer 使用ServerSocket实现的一个服务器,request根 ...
-
一个简单的web服务器
写在前面 新的一年了,新的开始,打算重新看一遍asp.net本质论这本书,再重新认识一下,查漏补缺,认认真真的过一遍. 一个简单的web服务器 首先需要引入命名空间: System.Net,关于网络编 ...
-
[置顶] 在Ubuntu下实现一个简单的Web服务器
要求: 实现一个简单的Web服务器,当服务器启动时要读取配置文件的路径.如果浏览器请求的文件是可执行的则称为CGI程序,服务器并不是将这个文件发给浏览器,而是在服务器端执行这个程序,将它的标准输出发给 ...
随机推荐
-
Markdown通用的常用语法说明
前言 Markdown 是一种轻量级的 标记语言,语法简洁明了.学习容易,还具有其他很多优点,目前被越来越多的人用来写作使用. Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表 ...
-
C++知识回顾(二)——名称空间
随着工程的增大,名称相互冲突的肯能性增加,使用多个厂商的类库时,可能导致名称冲突.为了解决这些问题,需要用到名称空间. 为了将代码加入名称空间,可以使用namespae将其包含,例如,编写一段代码,其 ...
-
codeforces 360 D - Remainders Game
D - Remainders Game Description Today Pari and Arya are playing a game called Remainders. Pari choos ...
-
Hibernate 小阶段总结
(一)Hibernate入门 通俗的话来说:Hibernate是用于面向对象操控数据库,对JDBC进行轻量级封装.(在java世界中传统的来说是JDBC访问数据库.) 1)Hibernate定性:对象 ...
-
phonegap 框架详解
首先, 来看一下phonegap 初始化流程以及Native 与 JS 交互流程图. 说明:socket server模式下, phonegap.js 源码实现的采用1 毫秒执行一次XHR请求, 当 ...
-
Knockoutjs实例 - 属性绑定(Bindings)之流程控制(Control flow)
一.foreach binding 使用此功能可以方便我们循环遍历输出某个数组.集合中的内容. (1).循环遍历输出数组 View Row Code 1 <script type="t ...
-
php判断 !==false
测试 if($res !== false){ echo "未定义通过<br>"; }else{ echo "未定义不通过<br>"; } ...
-
JavaScript之简易计算器
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...
-
BZOJ 1634: [Usaco2007 Jan]Protecting the Flowers 护花
Description Farmer John went to cut some wood and left N (2 <= N <= 100,000) cows eating the g ...
-
UVA 11768 - Lattice Point or Not(数论)
UVA 11768 - Lattice Point or Not option=com_onlinejudge&Itemid=8&page=show_problem&categ ...