Node.jsで静的ファイルをレスポンスする方法

静的ファイルを効率的に扱い、セキュリティを強化するためのNode.jsの活用方法を学びましょう。このガイドでは、HTTPサーバーの設定からパスの解析まで、Node.jsで静的ファイルをハンドリングするためのステップを詳しく解説します。

はじめに

今回、静的ファイルのルーティング方法について解説します。

ここでは、以下のバージョンを使用した、ルーティング方法を説明します。

nodejs v19.7.0

また、今回作成するコードは全て、GitHubに掲載しています。

静的ファイルのルーティング

静的ファイルを提供する最小限のコードは以下の通りです。

server.js

var http = require("http");
var fs = require("fs");
var path = require("path");

http
  .createServer(function (request, response) {
    var filePath = "." + request.url;
    if (filePath == "./") filePath = "./index.html";

    var extname = String(path.extname(filePath)).toLowerCase();
    var contentType = "text/html";
    var mimeTypes = {
      ".html": "text/html",
      ".js": "text/javascript",
      ".css": "text/css",
      ".json": "application/json",
      ".png": "image/png",
      ".jpg": "image/jpg",
      ".gif": "image/gif",
      ".wav": "audio/wav",
      ".mp4": "video/mp4",
      ".woff": "application/font-woff",
      ".ttf": "application/font-ttf",
      ".eot": "application/vnd.ms-fontobject",
      ".otf": "application/font-otf",
      ".svg": "application/image/svg+xml",
    };

    contentType = mimeTypes[extname] || "application/octet-stream";

    fs.readFile(filePath, function (error, content) {
      if (error) {
        if (error.code == "ENOENT") {
          fs.readFile("./404.html", function (error, content) {
            response.writeHead(200, { "Content-Type": contentType });
            response.end(content, "utf-8");
          });
        } else {
          response.writeHead(500);
          response.end(
            "Sorry, check with the site admin for error: " +
              error.code +
              " ..\n"
          );
          response.end();
        }
      } else {
        response.writeHead(200, { "Content-Type": contentType });
        response.end(content, "utf-8");
      }
    });
  })
  .listen(3000, () => console.log("listening on http://localhost:3000"));

解説

  • モジュールのインポート
var http = require('http');
var fs = require('fs');
var path = require('path');

上記コードでは、HTTPサーバーを作成するためのhttpモジュール、ファイルシステムを操作するためのfsモジュール、そしてファイルパスを操作するためのpathモジュールを読み込んでいます。

  • HTTPサーバーの作成
http.createServer(function (request, response) {
    // コード省略
}).listen(3000, () => console.log("listening on http://localhost:3000"));

このコードは、3000番ポートでHTTPサーバーを起動します。サーバーが正常に起動すると、’listening on http://localhost:3000’というメッセージがコンソールに表示されます。createServer関数内部では、リクエストが来るたびに呼び出されるコールバック関数を設定しています。

  • ファイルパスの解析
var filePath = '.' + request.url;
if (filePath == './')
    filePath = './index.html';

ここでは、リクエストURLから静的ファイルのパスを生成しています。リクエストがルート(’/’)に対するものであれば、デフォルトのインデックスファイル(index.html)を返すようにしています。

  • ファイルの読み込みとレスポンスの生成
fs.readFile(filePath, function(error, content) {
    // コード省略
});

上記のコードでは、解析したファイルパスからファイルを読み込み、読み込んだ内容をHTTPレスポンスとしてクライアントに返しています。エラーが発生した場合(例えばファイルが見つからない場合)は、適切なエラーレスポンスを生成します。

これにより、Webブラウザなどからhttp://localhost:3000/[ファイル名]というURLで直接アクセスすることができ、指定した静的ファイルを取得することができます。

index.html

<h1>Hello World</h1>

テスト

上記のコードを実行して、http://localhost:3000/にアクセスしてみましょう。以下のような画面が表示されれば成功です。

まとめ

この記事では、Node.jsで静的ファイルを提供する方法について解説しました。今回は、HTTPサーバーの設定と静的ファイルへのルーティングについて説明しました。 HTMLファイルなどの静的ファイルを提供するだけであれば、上記のコードで十分です。しかし、実際のWebアプリケーションでは、静的ファイルだけでなく、動的なコンテンツを提供する必要があります。