Node.js WEBサーバを構築するための例示的なコード


前言
ここ数日、vue.jsの枠組みを熟知するために、webpackの使用もあります。markdwonを公開して閲覧する簡単なWEBアプリケーションを構築します。バックグラウンドサービスとしてbashスクリプトとbusyboxのhttpdを利用したいのですが、Bashスクリプトの解析とJSONの生成は非常に不便で、Java言語で書くのは不便なので、使っているNode.jsを思い出しました。文末に本文コードのgithubアドレスがあります。)
簡単な例
まず、最も簡単なHello world を構築することから、以下のディレクトリ、ファイル、コンテンツを作成します。
プロジェクトの作成と実行
プロジェクト

web-server
+ | - server.js
server.js

const http = require('http');

http.createServer(function(request, response) {
 //      
 response.writeHeader(200, {
  "Content-Type" : "text/plain"
 });
 //       "Hello world!"
 response.write("Hello world!");
 response.end();
})
//        9000
.listen(9000);

現在、プロジェクトディレクトリの実行下のコマンドでserver.jsを実行します。ブラウザのアドレス欄にlocal host:9000を入力してください。すべてのアクセスが正常であれば、ブラウザにハローワールドが表示されます。node server.jsヒント:ctrl+cを使ってスクリプトの運転を停止します。
これまでの簡単な例で実行に成功しました。コードを分析します。
コード解析
まず、server.jsにはNode.jsのhttpモジュールが導入されており、非常下のHTTP APIのサポートが提供されている。ここでは、createServer()方法を使用して、http.serverの例を返し、このインスタンスのlisten()方法を使用して傍受ポートを設定する。
メソッドcreateSever()に記載されているパラメータは、Requestイベントに自動的にコールバック関数として追加されます。パラメータの種類はhttp.IncompingMessageとhttp.ServerResonseです。コールバック関数では、http.ServerResonseの方法で応答ヘッダと応答本体を設定し、最後にend()の方法で今回の要求を終了します。
ルート機能
上記の例は単なる要求応答機能を実現しただけで、現在はルートの機能を増加させて、我々のWEBサーバを強化しています。以下のディレクトリ、ファイル、内容に変更します。
簡単なルートを実現
プロジェクト

web-server
 | - server.js
+ | - router.js
server.js

const http = require('http');
const router = require('./router.js');

function handleHello(request, response) {
 //      
 response.writeHeader(200, {
  "Content-Type" : "text/plain"
 });
 //       "Hello world!"
 response.write("Hello world!");
 response.end();
}

http.createServer(function(request, response) {
 //             
 router.register(request, response, [
  {
   'url': '/hello',
   'handler': handleHello
  }
 ]);
})
//        9000
.listen(9000);
router.js

const url = require('url');

exports.register = function(request, response, mapping) {
 //       
 var pathName = url.parse(request.url).pathname;
 //              
 for(let i = 0, len = mapping.length;i < len;i++) {
  if(mapping[i].url === pathName) {
   mapping[i].handler(request, response);
   return;
  }
 }
 //          404  
 response.writeHeader(404, {
  "Content-Type" : "text/html"
 });
 response.end(`
  <html>
   <head>
    <title>NOT FOUND</title>
   </head>
   <body>
    <h1>404 NOT FOUND</h1>
   </body>
  </html>
 `);
}
今、再度server.jsスクリプトを実行して、ブラウザでlocal host:9000\helloにアクセスしてハローworldをもらうことができます。の結果として、他のパスにアクセスすると404ページが得られます。
この機能のコア実装は、router.jsにおいて、要求経路の解析を通じて、予め登録されたmapping配列に基づいて、対応する経路を見つけ、対応するコールバック関数を実行することである。
静的リソース要求
現在のルーティング機能はコールバック関数の実行しかできません。一方、WEBサーバは、静的リソース要求に応答する能力を持っています。次に、私たちは引き続きそれを改造します。現在、server.jsの内容はそのままにして、router.jsの内容だけを変更します。
route.js

const url = require('url');
const path = require('path');
const fs = require('fs');

function getErrorInfo(errorType) {
 //     
}

function writeErrorPage(response, errorType) {
 //     
}

exports.register = function(request, response, mapping) {
 //       
 var pathName = url.parse(request.url).pathname;
 //              
 for(let i = 0, len = mapping.length;i < len;i++) {
  if(mapping[i].url === pathName) {
   mapping[i].handler(request, response);
   return;
  }
 }
 //              
 var file = path.resolve(__dirname, '.' + pathName);
 fs.exists(file, function(exists) {
  //          404  
  if(!exists) {
   writeErrorPage(response, 'NOT_FOUND');
  }
  else {
   var stat = fs.statSync(file);
   //          403  
   if(stat.isDirectory()) {
    writeErrorPage(response, 'FORBIDDEN');
   }
   else {
    response.writeHeader(200, {
     "Content-Type" : "text/html"
    });
    response.end(
     fs.readFileSync(file, 'utf-8')
    );
   }
  }
 });
}
静的リソース要求の挙動を設定した設計は、コールバック関数が必ず実行できることを保証するためである。静的リソースが存在しない場合は、存在しないエラーを返します。ディレクトリへのアクセスを禁止するルールも設定されています。
後の話
今は、WEBサーバの基本的な機能を実現しただけで、まだ大きな改善スペースがあります。私はプロジェクトをgithubに展開します。興味のあるものはクローンできます。皆さんの勉強に役に立つように、私たちを応援してください。