Node.js学习笔记(五) --- 使用Node.js搭建Web服务器
1、 Node.js 创建的第一个应用
1、引入http模块
var http = require("http");
2、 创建服务器
接下来我们使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 8888 端口。函数通过 request, response 参数来接收和响应数据。
//1.引入 http 模块 var http=require('http'); //2.用 http 模块创建服务 http.createServer(function(req,res){ // 发送 HTTP 头部 // HTTP 状态值: 200 : OK //设置 HTTP 头部,状态码是 200,文件类型是 html,字符集是 utf-8 res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"}); res.write('你好 nodejs'); res.write('我是第一个 nodejs 程序'); res.end(); /*结束响应*/ }).listen(8001);
2、 WEB 服务器介绍
Web 服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等 Web 客户端提供文档, 也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个 Web 服务器是 Apache 、 Nginx 、IIS。
3、 Nodejs 封装一个 WEB 服务器
启动
node start
功能
* 能显示以 `.html/.htm` 结尾的 Web 页面 * 能直接打开以 `.js/.css/.json/.text` 结尾的文件内容 * 显示图片资源 * 自动下载以 `.apk/.docx/.zip` 结尾的文件 * 形如 `http://xxx.com/a/b/` , 则查找b目录下是否有 `index.html`,如果有就显示,如果没有就列出该目录下的所有文件及文件夹,并可以进一步访问。 * 形如 `http://xxx.com/a/b`, 则作301重定向到 `http://xxx.com/a/b/` , 这样可以解决内部资源引用错位的问题。
HttpServer.js
module.exports = (function () { "use strict"; console.time('[HttpServer][Start]'); //http协议模块 var http = require('http'); //url解析模块 var url = require('url'); //文件系统模块 var fs = require("fs"); //路径解析模块 var path = require("path"); return { //启动服务 start: function () { var port = this.config.port; var ip = this.config.ip; //创建一个服务 var httpServer = http.createServer(this.processRequest.bind(this)); //在指定的端口监听服务 httpServer.listen(port, function () { console.log("[HttpServer][Start]", "runing at http://" + ip + ":" + port + "/"); console.timeEnd("[HttpServer][Start]"); }); httpServer.on("error", function (error) { console.error(error); }); }, /** * 请求处理 * @param request * @param response */ processRequest: function (request, response) { var hasExt = true; var requestUrl = request.url; var pathName = url.parse(requestUrl).pathname; //对请求的路径进行解码,防止中文乱码 pathName = decodeURI(pathName); //如果路径中没有扩展名 if ((pathName) === '') { //如果不是以/结尾的,加/并作301重定向 if (pathName.charAt(pathName.length - 1) != "/") { pathName += "/"; var redirect = "http://" + request.headers.host + pathName; response.writeHead(301, { location: redirect }); response.end(); return; //fix bug: 执行301重定向后应终止后续流程,以防 "write after end" 异常 } //添加默认的访问页面,但这个页面不一定存在,后面会处理 pathName += "index.html"; hasExt = false; //标记默认页面是程序自动添加的 } //获取资源文件的相对路径 var filePath = path.join("http/webroot", pathName); //获取对应文件的文档类型 var contentType = this.getContentType(filePath); //如果文件名存在 fs.exists(filePath, function (exists) { if (exists) { response.writeHead(200, {"content-type": contentType}); var stream = fs.createReadStream(filePath, {flags: "r", encoding: null}); stream.on("error", function () { response.writeHead(500, {"content-type": "text/html"}); response.end("<h1>500 Server Error</h1>"); }); //返回文件内容 stream.pipe(response); } else { //文件名不存在的情况 if (hasExt) { //如果这个文件不是程序自动添加的,直接返回404 response.writeHead(404, {"content-type": "text/html"}); response.end("<h1>404 Not Found</h1>"); } else { //如果文件是程序自动添加的且不存在,则表示用户希望访问的是该目录下的文件列表 var html = "<head><meta charset='utf-8'></head>"; try { //用户访问目录 var filedir = filePath.substring(0, filePath.lastIndexOf('\\')); //获取用户访问路径下的文件列表 var files = fs.readdirSync(filedir); //将访问路径下的所以文件一一列举出来,并添加超链接,以便用户进一步访问 for (var i in files) { var filename = files[i]; html += "<div><a href='" + filename + "'>" + filename + "</a></div>"; } } catch (e) { html += "<h1>您访问的目录不存在</h1>" } response.writeHead(200, {"content-type": "text/html"}); response.end(html); } } }); }, /** * 获取文档的内容类型 * @param filePath * @returns {*} */ getContentType: function (filePath) { var contentType = this.config.mime; var ext = path.extname(filePath).substr(1); if (contentType.hasOwnProperty(ext)) { return contentType[ext]; } else { return contentType.default; } }, ///配置信息 config: { port: 8888, ip: '127.0.0.1', mime: { html: "text/html", js: "text/javascript", css: "text/css", gif: "image/gif", jpg: "image/jpeg", png: "image/png", ico: "image/icon", txt: "text/plain", json: "application/json", default: "application/octet-stream" } } } })();
start.js
var http = require('./http/HttpServer'); http.start();
源代码
链接: https://pan.baidu.com/s/1JyrlKCslVjryAfHKzmWz6g 提取码: 3gyn