学习用node.js建立一个简单的web服务器
一、建立简单的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程序,服务器并不是将这个文件发给浏览器,而是在服务器端执行这个程序,将它的标准输出发给 ...
随机推荐
- char 与 unsigned char的区别和取值范围
1.char和unsigned char 都是一个byte,8个bit.char是无符号类型,首位bit是符号位. 2.取值范围不同: (1)unsigned char的取值范围:0~2^8-1(0~ ...
- 源码方式安装rabbitmq
由于工作环境中属于内网,yum安装方式不可用,所以需要采用源码进行rabbitmq的安装.rabbitmq是基于erlang环境进行运行的,所以需要先按照erlang环境,才能运行rabbitmq-s ...
- 【转】ROWNUM与ORDER BY先后关系
源地址:http://www.cnblogs.com/accumulater/p/6137385.html
- LinkedList实现原理
原文链接:https://www.jianshu.com/p/56c77c517e71 本文对LinkedList的实现讨论都基于JDK8版本 Java中的LinkedList类实现了List接口和D ...
- 4、OpenCV Python 像素运算
__author__ = "WSX" import cv2 as cv import numpy as np #前提需要运算的图像大小和类型完全相同 #算术运算 加减乘除 #逻辑运 ...
- Vue中添加过渡效果
最近在学习Vue这个框架,发现新的版本中,官网的文档里面说的过渡效果,如果直接粘贴官方的例子中的代码,发现并没有过渡的效果,经过反复测试之后终于知道怎么搞了,把测试的过程总结一下,以便以后回顾. 贴上 ...
- poj3321(dfs序+树状数组)
题目链接:https://vjudge.net/problem/POJ-3321 题意:给一个普通树(不是二叉树),并且已经编号,每个结点为1或0,有两种操作,对单个结点修改和查询一个结点的子树的所有 ...
- Django 11 form表单(状态保持session、form表单及注册实现)
Django 11 form表单(状态保持session.form表单及注册实现) 一.状态保持 session 状态保持 #1.http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状 ...
- maven 发布 到 远程 tomcat
需要修改3个地方 首先 maven setting.xml 在 servers 节点 中 添加 一个 server <server> <id>devTomcat</id& ...
- C语言中的预处理命令
预处理功能是C语言的重要功能. 问:为什么要预处理,什么是预处理? 答:我们知道高级语言的运行过程是通过编译程序(编译器)把源代码翻译成机器语言,实现运行的.编译程序的工作包含:语法分析.词法分析.代 ...