Node.js创建HTTP文件服务器步骤详解

这次给大家带来Node.js创建HTTP文件服务器步骤详解,Node.js创建HTTP文件服务器的注意事项有哪些,下面就是实战案例,一起来看一下。

HelloWorld示例只有演示意义,这次我们来搞一个实际的例子:文件服务器。我们使用Node.js创建一个HTTP协议的文件服务器,你可以使用浏览器或其它下载工具到文件服务器上下载文件。

为了读取文件,我们会用到File System模块(名字是”fs”),Stream,我们还要分析URL,区别HTTP方法,还会用到EventEmitter。

文件服务器FileServer的代码

先上代码吧,依然是简单的:

// 引入http模块var http = require("http"); var fs = require("fs");// 创建server,指定处理客户端请求的函数http.createServer(  function(request, response) {    //判断HTTP方法,只处理GET     if(request.method != "GET"){      response.writeHead(403);      response.end();      return null;    }    //此处也可使用URL模块来分析URL(https://nodejs.org/api/url.html)    var sep = request.url.indexOf('?');    var filePath = sep < 0 ? request.url : request.url.slice(0, sep);    console.log("GET file: " + filePath);    //当文件存在时发送数据给客户端,否则404    var fileStat = fs.stat("."+filePath,       function(err, stats){        if(err) {          response.writeHead(404);          response.end();          return null;        }        //TODO:Content-Type应该根据文件类型设置        response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": stats.size});        //使用Stream        var stream = fs.createReadStream("."+filePath);        stream.on('data',function(chunk){          response.write(chunk);        });        stream.on('end',function(){          response.end();        });        stream.on('error',function(){          response.end();        });      }    );  }).listen(8000); console.log("Hello World start listen on port 8000");

登录后复制

最大的变化,就在传递给createServer方法的参数了。

我们根据request.method作了判断,不是GET就返回403。如果是呢,就判断文件是否存在,不存在,返回404,存在就读取数据写给客户端。逻辑就是这么简单。下面我们来介绍用到的新知识。

File System

要使用FileSystem,得用require引入fs模块,就如前面代码里那样。File System的API老长老长了,看这里吧:https://nodejs.org/api/fs.html。我们只说用到的特性。

获取文件状态

在我们的FileServer里,收到和客户端请求时先通过fs.stat()方法获取文件状态。fs.stat()方法原型如下:

fs.stat(path, callback)

登录后复制

第一个参数是文件路径,第二个参数是回调函数。fs.stat()方法是异步的,结果通过回调函数callback返回。callback的原型如下:

function(err, stats)

登录后复制

第一个参数指示是否出现了错误,第二个参数是一个对象,类型是fs.Stats,保存了文件的状态信息,比如大小、创建时间、修改时间等。

FileServer的代码获取到文件状态后,读取大小,调用http.ServerResponse的writeHead方法,设置HTTP状态码为200,还设置了Content-Length头部。代码如下:

复制代码 代码如下:

response.writeHead(200, {“Content-Type”: “text/plain”, “Content-Length”: stats.size})

ReadStream

接下来呢,我们调用fs.createReadStream创建了一个ReadStream对象。ReadStream是Stream,也是EventEmitter。

fs.createReadStream方法原型如下:

fs.createReadStream(path[, options])

登录后复制

第一个参数是文件路径,第二个参数是可选的JSON对象,用来指定打开文件的一些选项,默认值如下:

{ flags: ‘r', encoding: null, fd: null, mode: 0666, autoClose: true }

登录后复制

autoClose属性默认为true,读完文件或读取出错时,文件会被自动关闭。fd属性可以关联一个已有的文件描述符,这样就会忽略path,根据一个已经打开的文件来创建流。options还可以有start和end项,指定起、止位置,读取文件的特定区域。如果我们要实现断点续传,就需要这个了,用法类似这样:

fs.createReadStream('sample.mp4', {start: 1000, end: 10000});

登录后复制

encoding用来指定文件的编码,这对于文本文件有特殊的意义,目前支持’utf8’、’ascii’和’base64’。

ReadStream读取数据是异步的,一块一块的读,读到一部分就发送一个data事件,数据呢,会传递给与事件关联的listener(实际上是一个回调方法)。在我们的代码里,仅仅是调用response.write把数据写给客户端。注意,可能会多次调用response.write哦。又因为我们设置了Content-Length,所以不会采用chunked编码方式。如果我们不设置Content-Length,那默认会启用chunked方式。

ReadStream读完文件时会发射end事件,出错时会发射error事件,我们监听这两个事件,简单的终止响应。

我们在示例代码中看到了stream.on这种代码,下面来解释吧。

EventEmitter

Node.js基于V8引擎实现的事件驱动IO,是其最大最棒的特色之一。有了事件机制,就可以充分利用异步IO突破单线程编程模型的性能瓶颈,使得用JavaScript作后端开发有了实际意义。

EventEmitter的基本用法

events.EventEmitter是一个简单的事件发射器的实现,具有addListener、on、once、removeListener、emit等方法,开发者可以很方便的调用这些API监听某个事件或者发射某个事件。

我们在示例中用到的fs.ReadStream就是一个EventEmitter,它实现了stream.Readable接口,而stream.Readable具有data、error、end、close、readable等事件。

通常我们使用EventEmitter的on或addListener来监听一个事件,这个时间可能会多次触发,每次触发,我们提供的回调方法都会被调用。我们示例中的代码就是这样:

    stream.on('data',function(chunk){      response.write(chunk);    });

登录后复制

Node.js的事件机制,会给某个事件关联一个回调方法列表,这样多个关注者就可以监听同一个事件。每个事件发射时,可能会带有数据和状态,这些数据是通过回调方法的参数传递出来的。那某一个特定的事件,它对应的回调方法的参数是什么样子的,则由事件定义的那个类(实例)来决定。EventEmitter的emit方法原型如下:

emitter.emit(event[, arg1][, arg2][, ...])

登录后复制

这个原型说明一个事件的回调方法可以有一个或多个参数,也可以没有参数。要想知道某个事件的回调方法是否有参数、每个参数的含义,只好去找相关的API文档。stream.Readable的data事件的参数是chunk,Buffer类型,代表读到的数据。

如果我们只想监听某个事件一次,则可以调用EventEmitter的once方法。要想移除一个事件监听器,可以调用removeListener,想移除所有,则可以调用removeAllListener。

自定义事件

Node.js的很多模块都继承自Event模块。我们自己也可以通过继承EventEmitter来实现自己的对象,添加自己的自定义事件。

这里有个简单的例子:

var util=require("util");var events = require("events");function Ticker() {  var self = this;  events.EventEmitter.call(this);  setInterval(function(){    self.emit("tick")    },    1000  );}util.inherits(Ticker, events.EventEmitter);var ticker = new Ticker();ticker.on("tick", function() { console.log("tick event");});

登录后复制

在这个简单的例子里,我们定义了Ticker对象,通过全局方法setInterval开启了一个定时器,每隔1000毫秒发射一个名为“tick”的事件。

Node.js的工具模块封装了继承的方法,我们调用它来的inherits方法来完成Ticker对events.EventEmitter的继承。

自定义事件的使用方法,和Node.js内置模块提供的事件的用法完全一样。

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

table表格内对某列内容进行搜索筛选步骤详解

node前端模板引擎Jade标签使用详解

以上就是Node.js创建HTTP文件服务器步骤详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2759845.html

(0)
上一篇 2025年3月8日 08:45:28
下一篇 2025年3月8日 01:16:01

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Node.js使用Angular步骤详解

    这次给大家带来Node.js使用Angular步骤详解,Node.js使用Angular的注意事项有哪些,下面就是实战案例,一起来看一下。 在“使用AngularJS”中,我们提到了如何在Node.js项目中引入AngularJS,这次提供…

    2025年3月8日
    200
  • JS内数组合并方法与对象合并实现步骤详解

    这次给大家带来JS内数组合并方法与对象合并实现步骤详解,JS内数组合并方法与对象合并实现的注意事项有哪些,下面就是实战案例,一起来看一下。 1 数组合并 1.1 concat 方法 var a=[1,2,3],b=[4,5,6];var c…

    编程技术 2025年3月8日
    200
  • Node.js使用对话框ngDialog实现步骤详解

    这次给大家带来Node.js使用对话框ngDialog实现步骤详解,Node.js使用对话框ngDialog的注意事项有哪些,下面就是实战案例,一起来看一下。 做网站经常会遇到弹出对话框获取用户输入或弹出对话框让用户确认某个操作之类的情景,…

    编程技术 2025年3月8日
    200
  • 解析Vue.js下载方式及使用步骤

    这次给大家带来解析Vue.js下载方式及使用步骤,解析Vue.js下载方式及使用的注意事项有哪些,下面就是实战案例,一起来看一下。 vue.js是什么? Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。…

    编程技术 2025年3月8日
    200
  • AngularJS模态框模板ngDialog使用案例分享

    这次给大家带来AngularJS模态框模板ngDialog使用案例分享,AngularJS模态框模板ngDialog使用的注意事项有哪些,下面就是实战案例,一起来看一下。 项目开始的时候我们用的对话框是AngularJS的$modal模态框…

    编程技术 2025年3月8日
    200
  • JS实现一个简易的计算器步骤详解

    这次给大家带来JS实现一个简易的计算器步骤详解,JS实现一个简易的计算器的注意事项有哪些,下面就是实战案例,一起来看一下。 自己期末复习的时候就一直想要写一个计算器,闲暇的时候也在想具体怎么实现,觉得应该不难,但就是想写。昨天终于可以开始动…

    2025年3月8日
    200
  • node.js 命令行工具使用详解

    这次给大家带来node.js 命令行工具使用详解,node.js 命令行工具使用的注意事项有哪些,下面就是实战案例,一起来看一下。 一. 先了解一下package.json 每个项目的根目录都有一个 package.json 文件,定义了这…

    2025年3月8日 编程技术
    200
  • js正则相关使用案例分享

    这次给大家带来js正则相关使用案例分享,js正则相关使用的注意事项有哪些,下面就是实战案例,一起来看一下。 JS正则表达式一条龙讲解(从原理和语法到JS正则) JS正则表达式大全(整理详细且实用) vaScript动态正则表达式问题请问正则…

    2025年3月8日
    200
  • JS Promise案例代码解析

    这次给大家带来JS Promise案例代码解析,JS Promise案例代码解析的注意事项有哪些,下面就是实战案例,一起来看一下。 1、约定 本文的 demo 代码有些是伪代码,不可以直接执行。 没有特殊说明,本文所有 demo 都是基于 …

    2025年3月8日
    200
  • JS中JSON对象定义与取值实现步骤详解

    这次给大家带来JS中JSON对象定义与取值实现步骤详解,JS中JSON对象定义与取值实现的注意事项有哪些,下面就是实战案例,一起来看一下。 1.JSON(JavaScript Object Notation)一种简单的数据格式,比xml更轻…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论