用nodejs搭建简易的HTTP服务器
声明:本文主要参考 Node入门 http://www.nodebeginner.org/index-zh-cn.html,向此电子书的作者Manuel Kiessling及译者goddyzhao & GrayZhang & MondayChen表示衷心感谢。
注:本文提到的代码已经上传到github:https://github.com/galian123/nodejs_http_server
可以通过git clone https://github.com/galian123/nodejs_http_server
获取到。
或者,直接打开https://github.com/galian123/nodejs_http_server,点击页面中中的“Clone or download”,然后点击“Download ZIP”。
目的
- (1)学习nodejs相关知识
- (2)测试一些需要连接服务器的功能,可以自定义服务器返回给客户端的数据格式,例如文本、图片、json文件、xml文件等。
下载nodejs
下载地址:https://nodejs.org/en/download/
目前nodejs最新版本是v6.10.0。例如Windows 64中使用的nodejs:https://nodejs.org/dist/v6.10.0/node-v6.10.0-x64.msi
安装nodejs之后,检查node的是否安装好:
注:我是之前装的,所以不是最新版本。
$ node -v
v6.4.0
简易HTTP服务器的功能
主要是实现以下几个功能:
- (1)返回文本
- (2)返回小图片
- (3)返回大图片
其他功能根据以后的实际需求再增加。
相应的url分别为:监听端口为8888
- (1) http://localhost:8888/get?type=text
- (2) http://localhost:8888/get?type=image
- (3) http://localhost:8888/get?type=bigimage
对 http://localhost:8888/ 也有相应的处理,返回“Hello World”。
以后可能增加:
http://localhost:8888/get?type=longtext
http://localhost:8888/get?type=json
http://localhost:8888/get?type=xml
http://localhost:8888/get?type=video
还有可能添加upload功能,即,将get
替换为upload
。
目录结构
创建一个目录,例如nodejs
,在此目录下的文件结构如下:
$ tree
. 当前目录nodejs
|-- images
| |-- abracadabra.jpg 小图片
| `-- view.jpg 大图片
|-- index.js 服务器的主文件
|-- requestHandlers.js 处理Http请求
|-- router.js 将Http请求转发给处理函数(requestHandlers)
`-- server.js 创建HTTP服务器
1 directory, 6 files
index.js:服务器的主文件
var server = require("./server");
var router = require("./router");
var requestHandlers =require("./requestHandlers");
var handle = {}
handle["/"] = requestHandlers.hello;
handle["/get"] = requestHandlers.get;
server.start(router.route, handle);
server.js:创建HTTP服务器
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var urlObj = url.parse(request.url);
var pathname = urlObj.pathname;
var query = urlObj.query;
console.log("Request for " + pathname + " received." + " query: " + query);
route(pathname, query, handle, response);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
router.js:将Http请求转发给处理函数requestHandlers
function route(pathname, query, handle, response) {
console.log("route for " + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](query, response);
} else {
console.log("No request handler found for " + pathname);
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 not found");
response.end();
}
}
exports.route = route;
requestHandlers.js:处理Http请求
var querystring = require("querystring");
var fs = require("fs");
function getText(response) {
var text = "Winnie the Witch";
console.log(text);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(text);
response.end();
}
function getImage(response) {
console.log("getImage");
fs.readFile("./images/abracadabra.jpg", "binary", function(error, file) {
if(error) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(error + "\n");
response.end();
} else {
response.writeHead(200, {"Content-Type": "image/jpg"});
response.write(file, "binary");
response.end();
}
});
}
function getBigImage(response) {
console.log("getBigImage");
fs.readFile("./images/view.jpg", "binary", function(error, file) {
if(error) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(error + "\n");
response.end();
} else {
response.writeHead(200, {"Content-Type": "image/jpg"});
response.write(file, "binary");
response.end();
}
});
}
function get(query, response) {
console.log("query: " + query);
var queryObj = querystring.parse(query);
for (key in queryObj) {
console.log("key: " + key + ", value: " + queryObj[key]);
}
var type = queryObj["type"];
switch(type) {
case "text":
getText(response);
break;
case "image":
getImage(response);
break;
case "bigimage":
getBigImage(response);
break;
default:
var text = "type " + type + " is unknown.";
console.log(text);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(text);
response.end();
break;
}
}
function hello(query, response) {
console.log("Hello World");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
exports.get = get;
exports.hello = hello;
启动服务器
$ node index.js
Server has started.