如何使用node.js创建http文件服务器
这次给大家带来如何使用node.js创建http文件服务器,使用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内置模块提供的事件的用法完全一样。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是如何使用node.js创建http文件服务器的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

掌握HTTP301状态码的含义:网页重定向的常见应用场景随着互联网的迅猛发展,人们对网页交互的要求也越来越高。在网页设计领域,网页重定向是一种常见且重要的技术,通过HTTP301状态码来实现。本文将探讨HTTP301状态码的含义以及在网页重定向中的常见应用场景。HTTP301状态码是指永久重定向(PermanentRedirect)。当服务器接收到客户端发

HTTP状态码200:探索成功响应的含义与用途HTTP状态码是用来表示服务器响应状态的数字代码。其中,状态码200表示请求已成功被服务器处理。本文将探索HTTP状态码200的具体含义与用途。首先,让我们了解一下HTTP状态码的分类。状态码被分为五个类别,分别是1xx、2xx、3xx、4xx和5xx。其中,2xx表示成功的响应。而200是2xx中最常见的状态码

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

HTTP请求超时,服务器端常常会返回504GatewayTimeout状态码。该状态码表示服务器在执行某个请求时,经过一段时间后仍未能获取到请求所需的资源或完成请求的处理。它是5xx系列的状态码,表示服务器端遇到了临时的问题或过载,导致无法正确处理客户端的请求。在HTTP协议中,各种状态码都有特定的含义和用途,而504状态码则用于表示请求超时问题。在客户

如何在C++中实现HTTP流传输?使用Boost.Asio和asiohttps客户端库创建SSL流套接字。连接到服务器并发送HTTP请求。接收HTTP响应头并打印它们。接收HTTP响应正文并打印它。

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

解决方法:1、重试:可等待一段时间后重新尝试,或者刷新页面;2、检查服务器负载:检查服务器的CPU、内存和磁盘使用情况,如果超过了容量限制,可尝试优化服务器配置或增加服务器资源;3、检查服务器维护和升级:在服务器恢复正常之前,只能等待;4、检查网络连接:确保网络连接稳定,检查网络设备、防火墙或代理设置是否正确;5、确保缓存或CDN配置正确;6、联系服务器管理员等等。

JS-Torch简介JS-Torch是一种深度学习JavaScript库,其语法与PyTorch非常相似。它包含一个功能齐全的张量对象(可与跟踪梯度),深度学习层和函数,以及一个自动微分引擎。JS-Torch适用于在JavaScript中进行深度学习研究,并提供了许多方便的工具和函数来加速深度学习开发。图片PyTorch是一个开源的深度学习框架,由Meta的研究团队开发和维护。它提供了丰富的工具和库,用于构建和训练神经网络模型。PyTorch的设计理念是简单和灵活,易于使用,它的动态计算图特性使
