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++都不同的特性,其中一个就 ...
随机推荐
- “全栈2019”Java第六十章:如何定义接口
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- pandas如何统计所有列的空值,并转化为list?
统计所有列的空值:data.isnull().sum() 转化成list: df.isnull().sum().index.tolist() df.isnull().sum().values.toli ...
- 前端-chromeF12 谷歌开发者工具详解 Network篇
开发者工具初步介绍 chrome开发者工具最常用的四个功能模块: Elements:主要用来查看前面界面的html的Dom结构,和修改css的样式.css可以即时修改,即使显示.大大方便了开发者调试页 ...
- ubuntu15.04下安装jdk8
前几天手贱,删掉了ubuntu自带的java,最后安装时遇到了Picked up JAVA_TOOL_OPTIONS的问题,经过网上各种找,终于被我弄成功了.下面将经验下载下面供大家方便: jdk8的 ...
- dbproxy-user/pwd
dbproxy 的账号是统一的, 即连接dbproxy,连接主mysql ,连接从mysql 的账号必须一样, 为了隔离 即使用dbproxy的人感知不到mysql, 需要分离 配置文件 #dbpro ...
- nginx高性能WEB服务器系列之五--实战项目线上nginx多站点配置
nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...
- Python环境安装与升级
Python是跨平台的,它可以运行在Windows,Mac,Linux/Unix系统上,在Windows上写的Python程序,在Linux上也是能够运行的.目前,Python有两个大版本,一个是2. ...
- Hibernate 使用注释书写配置文件
Hibernate 使用注释 Hibernate使用注释有个好处就是我们不需要建立.hbm.xml文件,直接在实体类中添加注解就可以完成往数据库中进行数据操作 配置文件:hibernate.cfg.x ...
- 复制订阅服务器和 AlwaysOn 可用性组 (SQL Server)
https://docs.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/replication-subscri ...
- java多线程-线程间协作
大纲: wait.notify.notifyAll Condition 生产消费者 一.wait.notify.notifyAll wait.notify.notifyAll是Object的本地fin ...