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
Node.js学习笔记(五) --- 使用Node.js搭建Web服务器的更多相关文章
- Node.js学习笔记(4)——除了HTTP(服务器和客户端)部分
很多node入门的书里面都会在介绍node特性的时候说:单线程,异步式I/O,事件驱动. Node不是一门语言,它是运行在服务器端的开发平台,官方指定语言为javascript. 阻塞和线程: 线程在 ...
- ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测
一.开篇 在博客注册了三年,今天才决定写第一篇博客,警告自己不要懒!!! 二.关于ArcGIS JS 版本选择 在写这篇博客时ArcGIS JS 4.0正式版已经发布.它和3.x版本的不同是,Map不 ...
- Node.js 学习(五)Node.js 事件循环
Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发. Node.j ...
- JS学习笔记 (五) 函数进阶
1.函数基础 1.1 函数的基本概念 函数是一段JavaScript代码,只被定义一次,但是可以被调用或者执行许多次.函数是一种对象,可以设置属性,或调用方法. 函数中的参数分为实参和形参.其中,形参 ...
- js学习笔记第一课(js基础知识)
1.js代码在浏览器中执行. 2.js代码直接插入网页中需包含在 <script language="javascript"> js代码 </script> ...
- 【JS学习笔记】第一个JS效果——鼠标提示框
分析效果实现原理--鼠标提示框 样式:div的display 事件:onmouseover,onmouseout 编写JS的流程 布局:HTML+CSS 属性:确定需要修改哪些属性 事件:确定用户做哪 ...
- JS学习笔记(一)JS处理JSON数据
[摘抄]将JSON字符串转换为json对象的方法.在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键.例如:J ...
- cube.js 学习(五)cube.js joins 说明
cube.js 也支持join, 参考格式 joins: { TargetCubeName: { relationship: `belongsTo` || `hasMany` || `hasOne ...
- JS学习笔记(4)--js变量的生命周期
http://www.cnblogs.com/williamxiao/p/3499973.html 最近看国外经典教材的时候发现JavaScript与熟知的Java,C,C++都不同的特性,其中一个就 ...
随机推荐
- WordCount(JAVA实现)
201631103228,201631101227 1.项目需求 对程序设计语言源文件统计字符数.单词数.行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件. wc. ...
- codeVS 动态最大子段和
题目链接:戳我 对于最大子段和,我们只需要维护四个变量--maxl,maxr,maxs,sum(分别表示区间最大前缀子段和,区间最大后缀子段和,区间最大子段和,区间所有数的和) 然后合并的时候是这样的 ...
- [NOI2010]能量采集(莫比乌斯反演)
题面: bzoj luogu NOI2010能量采集 题解 读完题之后我们发现在每个产生贡献的点\((x1,y1)\)中,它与原点之间的点\((x2,y2)\)都满足\(x2|x1\),\(y2|y1 ...
- Weekly Contest 121
984. String Without AAA or BBB Given two integers A and B, return any string S such that: S has leng ...
- 一个简单的HTML病毒分析
一直就想写这篇东西了,仅仅是上班时说要上班,不写.回家后又忙着玩游戏,丢一边去了.如今仅仅好不务正业的开写了.希望头儿不会知道我的blog.哈哈 在非常久之前就对HTML的病毒非常感兴趣了,非常好奇怎 ...
- HTTP请求的两种方式get和post的区别
1,get从服务器获取数据:post向服务器发送数据: 2,安全性,get请求的数据会显示在地址栏中,post请求的数据放在http协议的消息体: 3,从提交数据的大小看,http协议本身没有限制数据 ...
- CSS3过渡效果 兼容IE6、IE7、IE8
<style> .box{ width:120px;height:40px;background:yellowgreen;line-height:40px;transition:width ...
- 可持久化数据结构QwQ(持续更新中)
可持久化留下的迹象 我们俯身欣赏 ——<膜你抄>By Menci&24OI Micardi最近在学可持久化的东西,可持久化线段树.可持久化并查集.可持久化01Trie......等 ...
- __getitem__
如果在类中定义了__getitem__()方法,那么他的实例对象(假设为P)就可以这样P[key]取值.当实例对象做P[key]运算时,就会调用类中的__getitem__()方法.
- 2016级算法第四次上机-E.Bamboo and the Ancient Spell
Bamboo and the Ancient Spell 分析 可能英文读题难度比较大,但是只要看到全大写的 "THE LONGEST COMMON SUBSEQUENCE !"应 ...