Node静的サーボ(構築サービス)

5920 ワード

きほんきのう
1行目のコードを急いで書くのではなく、基本的な機能についてどのような手順があるかを整理します.
  • ローカルで指定ポートに従ってhttp serverを起動し、クライアントからの要求
  • を待つ.
  • 要求が到着すると、要求urlに従って設定静的ファイルディレクトリをbaseとし、マッピングしてファイル位置
  • を得る.
  • ファイルが存在するかどうかを確認する
  • ファイルが存在しない場合、404ステータスコードに戻り、not foundページをクライアント
  • に送信する.
  • ファイルが存在する場合:
  • ファイル読み込み待ち
  • を開く.
  • response header
  • を設定する
  • は、クライアント
  • にファイルを送信する.
  • クライアントからの次の要求
  • を待つ.
    基本機能の実装
    コード構造nodejs-static-webserverディレクトリを作成し、ディレクトリ内でnpm initを実行してpackageを初期化する.jsonファイル.
    mkdir nodejs-static-webserver && cd "$_"
    // initialize package.json
    npm init

    次に、次のファイルディレクトリを作成します.
    -- config ---- default.json -- static-server.js -- app.js

    default.json
    {
        "port": 9527,
        "root": "/Users/sheila1227/Public",
        "indexPage": "index.html"
    }
    default.jsには、ポート番号、静的ファイルディレクトリ(root)、デフォルトページ(indexPage)などのデフォルト構成が格納されます.このような要求http://localhost:9527/myfiles/が到着すると、rootによるマッピング後のディレクトリ内にindexがある場合.htmlは、デフォルトの構成に従って、クライアントにindexを返します.htmlの内容.
    static-server.js
    const http = require('http');
    const path = require('path');
    const config = require('./config/default');
    
    class StaticServer {
        constructor() {
            this.port = config.port;
            this.root = config.root;
            this.indexPage = config.indexPage;
        }
    
        start() {
            http.createServer((req, res) => {
                const pathName = path.join(this.root, path.normalize(req.url));
                res.writeHead(200);
                res.end(`Requeste path: ${pathName}`);
            }).listen(this.port, err => {
                if (err) {
                    console.error(err);
                    console.info('Failed to start server');
                } else {
                    console.info(`Server started on port ${this.port}`);
                }
            });
        }
    }
    
    module.exports = StaticServer;

     
    このモジュールファイルでは、StaticServerクラスを宣言し、startメソッドを定義し、このメソッド内にserverオブジェクトを作成し、rquestイベントを傍受し、サーバをプロファイルで指定されたポートにバインドします.この段階では、どのリクエストに対しても、リクエストのファイルパスを一時的に区別せずに簡単に返す.pathモジュールは、接続および解析パスを正規化するために使用され、オペレーティングシステム間の差異をわざわざ処理する必要はありません.
    app.js
    const StaticServer = require('./static-server');
    
    (new StaticServer()).start();

     
    このファイルでは、上記のstatic-serverモジュールを呼び出し、StaticServerインスタンスを作成し、startメソッドを呼び出して静的リソースサーバを起動します.このファイルの後には、他の変更は必要ありません.静的リソースサーバのすべての改善はstatic-server.jsで発生します.
    ディレクトリの下でプログラムを起動すると、正常に起動したlogが表示されます.
    > node app.js
    
    Server started on port 9527

    ブラウザでアクセスすると、サーバがリクエストパスを直接返しているのがわかります.
    ルーティング処理
    以前は、クライアントにファイルの場所を返すように要求していましたが、実際のファイルを返すように置き換えました.
        routeHandler(pathName, req, res) {
            
        }
    
        start() {
            http.createServer((req, res) => {
                const pathName = path.join(this.root, path.normalize(req.url));
                this.routeHandler(pathName, req, res);
            }).listen(this.port, err => {
                ...
            });
        }

     
    ファイル送信は、routeHandlerによって処理される.
    静的ファイルの読み込み
    ファイルを読み込む前に、fs.statでファイルが存在するかどうかを検出し、ファイルが存在しない場合、コールバック関数はエラーを受信し、404応答を送信する.
       respondNotFound(req, res) {
            res.writeHead(404, {
                'Content-Type': 'text/html'
            });
            res.end(`

    Not Found

    The requested URL ${req.url} was not found on this server.

    `); } respondFile(pathName, req, res) { const readStream = fs.createReadStream(pathName); readStream.pipe(res); } routeHandler(pathName, req, res) { fs.stat(pathName, (err, stat) => { if (!err) { this.respondFile(pathName, req, res); } else { this.respondNotFound(req, res); } }); }

     
    Note:
    ここでは、createReadStreamではなくストリーム形式のreadFileを使用します.これは、後者が完全なファイル内容を得る前にメモリに先に読み込むためです.これで万一ファイルが大きいと、複数のリクエストが同時にアクセスされ、readFileは耐えられなくなります.ファイル読み取り可能なストリームを使用すると、サービス側はデータがメモリに完全にロードされるまでクライアントに返信するのではなく、読み取りながらブロック応答を送信します.この場合、応答には次の応答ヘッダが含まれます.
    Transfer-Encoding:chunked

    デフォルトでは、読み取り可能なストリームが終了すると、書き込み可能なストリームのend()メソッドが呼び出されます.