Maison > interface Web > js tutoriel > le corps du texte

Explication détaillée des étapes pour créer un serveur de fichiers HTTP avec Node.js

php中世界最好的语言
Libérer: 2018-05-22 10:36:52
original
1709 Les gens l'ont consulté

Cette fois, je vais vous donner une explication détaillée des étapes pour créer un serveur de fichiers HTTP avec Node.js. Quelles sont les précautions pour créer un serveur de fichiers HTTP avec Node.js. un cas pratique, jetons un coup d'oeil.

L'exemple HelloWorld est uniquement à des fins de démonstration. Cette fois, nous prendrons un exemple pratique : un serveur de fichiers. Nous utilisons Node.js pour créer un serveur de fichiers avec le protocole HTTP. Vous pouvez utiliser un navigateur ou d'autres outils de téléchargement pour télécharger des fichiers depuis le serveur de fichiers.

Afin de lire des fichiers, nous utiliserons le module File System (nommé "fs"), Stream Nous devons également analyser l'URL, distinguer la méthode HTTP et utiliser EventEmitter. .

File Server FileServer Code

Commençons par le code, c'est quand même simple :

// 引入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");
Copier après la connexion

Le plus gros Le le changement réside dans les paramètres passés à la méthode createServer.

Nous avons porté un jugement basé sur request.method. Si ce n'est pas GET, il renverra 403. Si tel est le cas, déterminez si le fichier existe. S'il n'existe pas, renvoyez 404. S'il existe, lisez les données et écrivez-les sur le client. La logique est aussi simple que cela. Nous présentons ci-dessous les nouvelles connaissances utilisées.

Système de fichiers

Pour utiliser FileSystem, vous devez utiliser require pour introduire le module fs, tout comme dans le code précédent. L'API de File System existe de longue date, jetez un œil ici : https://nodejs.org/api/fs.html. Nous ne parlons que des fonctionnalités utilisées.

Obtenir l'état du fichier

Dans notre FileServer, lors de la réception d'une demande du client, nous récupérons d'abord le fichier via fs.stat () état de la méthode. Le prototype de la méthode fs.stat() est le suivant :

fs.stat(path, callback)
Copier après la connexion

Le premier paramètre est le chemin du fichier et le deuxième paramètre est la fonction de rappel. La méthode fs.stat() est asynchrone et le résultat est renvoyé via la fonction de rappel. Le prototype de rappel est le suivant :

function(err, stats)
Copier après la connexion

Le premier paramètre indique si une erreur s'est produite. Le deuxième paramètre est un objet de type fs.Stats, qui enregistre les informations d'état du fichier, telles que. taille et temps de création, temps de modification, etc.

Une fois que le code FileServer a obtenu l'état du fichier, il lit la taille, appelle la méthode writeHead de http.ServerResponse, définit le code d'état HTTP sur 200 et définit également la longueur du contenu. en-tête. Le code est le suivant :

Copier le code Le code est le suivant :

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

ReadStream

Ensuite, nous appelons fs.createReadStream pour créer un objet ReadStream. ReadStream est un Stream et un EventEmitter.

Le prototype de la méthode fs.createReadStream est le suivant :

fs.createReadStream(path[, options])
Copier après la connexion

Le premier paramètre est le chemin du fichier, et le deuxième paramètre est un objet JSON facultatif utilisé pour spécifier certaines options d'ouverture du fichier. file. La valeur par défaut est la suivante :

{ flags: ‘r', 
encoding: null, 
fd: null, 
mode: 0666, 
autoClose: true 
}
Copier après la connexion

L'attribut autoClose est par défaut vrai. Lorsque le fichier est lu ou qu'une erreur se produit, le fichier sera automatiquement fermé. L'attribut fd peut être associé à un descripteur de fichier existant, de sorte que le chemin soit ignoré et que le flux soit créé sur la base d'un fichier déjà ouvert. Les options peuvent également avoir des éléments de début et de fin, spécifier les positions de début et de fin et lire des zones spécifiques du fichier. Si nous voulons implémenter la reprise du point d'arrêt, nous avons besoin de ceci. L'utilisation est similaire à celle-ci :

fs.createReadStream('sample.mp4', {start: 1000, end: 10000});
Copier après la connexion

l'encodage est utilisé pour spécifier l'encodage du fichier. Cela a une signification particulière pour les fichiers texte. 'utf8', 'ascii' et 'base64'.

ReadStream lit les données de manière asynchrone, en les lisant morceau par morceau, lors de la lecture d'une partie de celles-ci, il envoie un événement de données. Les données seront transmises à l'écouteur associé à l'événement (en fait une méthode de rappel). Dans notre code, nous appelons simplement réponse.write pour écrire les données sur le client. Notez que réponse.write peut être appelé plusieurs fois. Et comme nous définissons Content-Length, l’encodage fragmenté ne sera pas utilisé. Si nous ne définissons pas Content-Length, le mode fragmenté sera activé par défaut.

ReadStream émettra l'événement de fin lorsqu'il aura fini de lire le fichier, et il émettra l'événement d'erreur lorsqu'une erreur se produit. Nous écoutons ces deux événements et terminons simplement la réponse.

Nous avons vu du code comme stream.on dans l'exemple de code. Expliquons-le ci-dessous.

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);
    });
Copier après la connexion

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

emitter.emit(event[, arg1][, arg2][, ...])
Copier après la connexion

这个原型说明一个事件的回调方法可以有一个或多个参数,也可以没有参数。要想知道某个事件的回调方法是否有参数、每个参数的含义,只好去找相关的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");
});
Copier après la connexion

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

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

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

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal