035.2 Node.js Expressの基礎
Web Development Essentials | 2025/01/14

本章では、Node.js上で動作するWebアプリケーションフレームワーク「Express」の主な機能について説明します。前回の記事に引き続き、Node.jsの学習は実践を通じて徐々に慣れていくことが重要です。実際にコーディングを行いながら、学習を進めましょう!

 Node.js Expressとは

Expressとは、Node.jsで利用することができるWebアプリケーションフレームワークで、npm installコマンドから追加することができるモジュールの一種です。

アプリケーションフレームワークとは、Web開発に必要な機能やツールがパッケージ化されたもので、プログラムを効率的に記述する為の土台や設計図のようなものを指します。アプリケーションフレームワークを使用することで、記述するコードの簡潔さや可読性が向上し、よく使う機能(後述するサーバー構築やデータベース接続など)を提供して、開発効率が改善されることから「簡単にアプリの雛形を立ち上げることができるもの」と認識して頂いたら問題ないと思います。

Node.jsで利用ができるアプリケーションフレームワークには、いくつか種類はありますが、今回利用するExpressはシンプルな設計から初学者でも学びやすく、また「ミドルウェア」という仕組みを使った機能の拡張性にも優れています。

Webサーバの構築

それではExpressを使ってWebサーバを起動してみましょう。本章では、前章で作成したserver.jsを引き続き使用して、実際にコードを記述していきます。
※server.jsをまだ作成していない方は、こちらの記事からご確認ください。

①VSCodeのターミナルを開き、以下のコマンドを実行してnodeフォルダに移動しましょう。

■<Windowsの場合>

C:\Users\ユーザ名> cd $env:USERPROFILE\Desktop\lesson\node

■<Mac OSの場合>

> cd $HOME/Desktop/lesson/node

②以下のコマンドを実行してExpressをインストールしましょう。

■ターミナル

> npm  install express

インストールを実行すると、「node_modules」フォルダ、「package-lock.json」ファイルが、lessonフォルダ内に作成されることを確認しましょう。
※package-lock.jsonとは、npm installを実行した際に、実際にインストールされたパッケージのバージョンが記載されているファイルです。

➂インストールが完了したら、「server.js」ファイルを以下のように変更しましょう。

■server.js

const express = require('express');
const app = express();
const port = 3000;

app.listen(port, () => {console.log('サーバが起動しました。');});

上記内容では、require()メソッドを用いてexpressモジュールをインポートし、express()を実行することによりExpressアプリケーションを作成し、定数appに格納しています。これにより、定数appの中には必要なメソッドや変数が保持されるようになります。

次に、先ほどの定数appに対してサーバーを起動するメソッド、listen()メソッドを使用しています。listenメソッドの第一引数にはポート番号を指定し、この指定したポート番号でlocalhostに対してサーバーを起動します。

それでは、以下のようにターミナルでnodeコマンドを実行して、「サーバが起動しました。」と表示されたら起動は成功です。

■ターミナル

> node server.js
サーバが起動しました。

なお、上記までの記述ではWebサーバを起動するだけで、コンテンツを表示するようなは記述ありませんので、下記のように「http://localhost:3000」にアクセスしても「Cannot GET /」と表示されます。

これは、サーバがアクセスを受け付けたものの、要求されたGETリクエストに対するコンテンツが存在しないことを示していますが、この表示が確認できれば、Expressを使ったWebサーバの起動は成功です。

HTTPリクエストの処理

ページの表示や、ユーザーが入力したデータの送信などはHTTPリクエストを通して行われます。
expressモジュールではこれらのリクエストを効率的に処理し、適切なレスポンスをクライアントに提供する多様な機能を備えています。本項目では、HTTP リクエストを処理するためのget()メソッドとpost()メソッドについて説明します。

get()

概要:HTTP GETリクエストを処理することができるメソッドです。expressモジュールでWebサーバ起動時にコンテンツを表示するには「get()メソッド」を使用します。
get()メソッドの第一引数にはリクエストを受け取るパスを指定し、第二引数では、HTTPサーバがクライントからGETリクエストを受け取ると、指定したメソッド(コールバック関数)が実行されます。

コールバック関数には、リクエストに関する情報を持つ「リクエストオブジェクト」とレスポンスを送信するための「レスポンスオブジェクト」の2つのパラメータを持ち、引数で指定する変数の名前は自由に設定が可能です。慣習として第1引数はrequestやreq、第2引数はresponseやresといった変数名がよく使用されます。
試験でも省略した形式で出題されるかもしれないので、是非覚えておきましょう。
(※コールバック関数は試験にでないと思うので説明は割愛しますが、是非ご自身で学習してみてくださいね。)

それでは、server.jsファイルに以下の記述例を追記し、「http://localhost:3000」にアクセスしましょう。

■server.js

const express = require('express');
const app = express();
const port = 3000;

app.get("/",(request,responce) => {
    responce.send("<h1>Hello World</h1>");
});

app.listen(port, () => {
    console.log('サーバが起動しました。');
});

send()

概要:アクセスしてきリクエストに対してレスポンスを返すメソッドです。 今回の例では、「Hello World」という見出しを返すようにしてます。

記述を変更したら、先程と同様にserver.jsを使用して、Webサーバを起動します。
既にサーバを接続している方は、ターミナル上で「Ctrl」+「c」を入力してサーバーを停止後、再接続しましょう。

■ターミナル

> node server.js
サーバが起動しました。

サーバを起動後、「http://localhost:3000」にアクセスすると以下のように表示されていれば成功です。

これで、get()メソッドを使用してリクエストを送り、レスポンスが返ってきていることが確認できました。

次は、リクエストの中に含まれるURLパラメータについて紹介いたします。
(※URLパラメータとは、簡単にいうとWebアプリに対して、URLに特定の形式で引き渡すデータの事です)

クエリパラメーターの取得

AmazonなどのECサイトで買い物をしたいとき、検索などを使用して欲しい商品を探したりしたことがあるかと思います。これはクエリパラメータを取得することで実現することができます。

クエリパラメータ

概要:URLパラメータの一種で、URLの末尾に「key=value」のように値を含める送信方式で、「?」に続いてパラメータ名と値のペアを渡すことができます。また「&」で値を区切ると複数のパラメータを同時にWebサーバに渡すことが出来ます。
例えば、「http://example.com/search?city=tokyo&address=ginza」というURLでは、「city」というパラメータ名で「tokyo」という値を、「address」というパラメータ名で「ginza」という値を指定していることになります。

それでは、早速server.jsのget()メソッドの記述部分を、下記内容のように変更してみましょう。

■server.js

app.get("/", (req, res) => {
    res.send(req.query.text);
}); 

記述の内容を説明する前に、ブラウザで実際に確認してみましょう。サーバーを再起動して、URL「http://localhost:3000/?text=test」にアクセスします。

URLにアクセスすると、上記画像のように「text」プロパティの値として設定されている「test」という値が、ブラウザ上で表示されています。是非「test」の部分を他の文字列に変更してブラウザを再読み込みしてみてください。変更した内容がブラウザ上に表示されているかと思います。

server.jsでは、クライアントからのリクエストに含まれるパラメータ、つまり今回の例では「test」を「req.query」を使ってリクエストオブジェクトから取得しており、その値をsend()メソッドを使用して、レスポンスとして返しています。

指定方法では「req.query.パラメータ名」で取得することができ、今回の例では「req.query.text」と指定すると、取得することができます。

パスパラメーターの取得

ユーザ毎にログインをすることが出来るようなWebサイトでは、URLのパス上に各ユーザ毎に割り当てられたIDを用いて、サイトにアクセスすることがあります。このような場合、サーバとしては、ユーザー毎に異なる情報を取得しなければいけませんが、パスパラメータを取得することで実現することができます。

パスパラメータ

概要:URLパラメータの一種で、URLのパスの一部に埋め込まれる変数のような値のことを指します。

それでは先程と同様に、server.jsの記述を変更します。

■server.js

app.get("/:message", (req, res) => {
    res.send(req.params.message);
});

こちらも早速ブラウザで実際に確認してみましょう。サーバーを再起動して、URL「http://localhost:3000/test」にアクセスします。

URLにアクセスすると、上記画像のように「/test」と指定されている内容が、ブラウザ上で表示されています。クエリパラメータと同様に、「/test」の部分を変更してブラウザを再読み込みしてみましょう。変更した内容が表示されているかと思います。

server.jsでは、URLのパスとして「/:message」と設定していますが、「:(コロン)」で始まる箇所は動的に変動するパラメータとして扱われる為、上記表示例のように「/test」と指定すると「/:message」の箇所に「test」が代入されるようになります。

更に、クエリパラメータと同様に、クライアントからのリクエストに含まれるパラメータ、「test」を「req.params」を使ってリクエストオブジェクトから取得しており、その値をsend()メソッドを使用して、レスポンスとして返しています。

指定方法では「req.params.パラメータ名」で取得することができ、server.jsではパラメータ名を「/:message」と指定している為、「req.params.message」のように取得することができます。

ここまで2つのパラメータを紹介しましたが、それぞれのURLでの書き方や、パラメータ名の指定方法は試験に出題されやすい内容となります。出題されても判別できるようにしておきましょう。

post()

概要:getメソッドと同様にHTTP POSTリクエストを処理することができるメソッドです。GETメソッドでは、URLに値を含める方法などを紹介しましたが、POSTメソッドではパラメータや値をURLに表示せず、メッセージボディに見せたくない情報を格納してWebサーバにデータを送信することができます。

GETメソッド、POSTメソッドの詳しい説明はこちらの記事でも詳しく紹介しています。各メソッドの使い方や違いに不安がある方は、もう一度確認しておきましょう。

それでは実際にブラウザで確認してみましょう。server.jsを以下のように変更します。

■server.js

const express = require('express');
const app = express();
const port = 3000;

//ここから
const html = '<form action="/form" method="POST"><input type="text" name="name"><button type="submit">送信</button></form>';
app.get("/", (req, res) => {
    res.send(html);
});
//ここまでを追加

app.listen(port, () => {
    console.log('サーバが起動しました。');
});

上記のgetメソッドの記述では、<form>タグを使用して、送信ボタンを押下して「/form」ページにPOSTリクエストを送信できるように入力欄とボタンを追加しています。

これでフォームのHTMLは作成できましたが、この段階ではPOSTリクエストの処理を記述していない為、送信ボタンを押しても動作しません。
server.jsファイルに下記の内容を貼り付けて、POSTリクエストの設定を行いましょう。

■server.js

const express = require('express');
const app = express();
const port = 3000;
app.use(express.urlencoded({ extended: true })); //この行を追加

const html = '<form action="/form" method="POST"><input type="text" name="name"><button type="submit">送信</button></form>';
app.get("/", (req, res) => {
    res.send(html);
});

//ここから
app.post("/form", (req, res) => {
    res.send(`${req.body.name}さん、こんにちは`);
});
//ここまでを追加

app.listen(port, () => {
    console.log('サーバが起動しました。');
});

上記で追加した内容では、リクエストオブジェクトからbodyを取得し、nameプロパティの値をレスポンスとして返しています。
Expressでは、このリクエストオブジェクトからbodyのデータを扱うために「body-parser」という機能を使用することができます。

また、get()メソッドの上に追加した以下の記述では、urlencodeメソッドを使用してクライアントから送信されたデータを解析、参照しやすいようにオブジェクトに変換してくれています。

app.use(express.urlencoded({ extended: true }));

この記述に関しては、試験で問われる事はないかと思いますが、「body-parser」や「urlencode」メソッドは思い出せるようにしていた方がよいと思います。

それでは、実際にフォームから値を送信してみましょう。以下は、入力フォームに「テスト」と入力し、送信した場合の表示結果となります。

データを送信後、上記画像のように入力した内容の後に「さん、こんにちは」と表示がされたら成功です。

これまでは、sendメソッドを使用して、テキストを送信する例を紹介してきましたが、Expressのresponseオブジェクトで使える代表的なメソッドを他にも紹介いたします。

メソッド名前
response.send()さまざまなタイプのレスポンスを返す
response.render()テンプレートをレンダリングしてレスポンスを返す
response.json()JSONデータをレスポンスで返す
response.sendFile()ファイルを送信する

テンプレートエンジン

テンプレートエンジンとは、プログラムのデータを元にして、HTMLなどのテキストファイルを動的に生成する仕組みです。JavaScriptで使用できるテンプレートエンジンはいくつかありますが、その中でも、本試験にあわせてEJSを用いて説明いたします。

EJS(EmbeddedJavaScript)はJavaScriptの文法を使用して、HTMLにデータを埋め込むことができるテンプレートエンジンです。
EJSを使用するために、npmを使用してインストールしましょう。インストールするディレクトリはnodeディレクトリで実行するようにご注意ください。

■ターミナル

> npm install ejs

インストールが完了したら、次に「views」ディレクトリを作成します。mkdirコマンドのあとにviewsと指定しましょう。

■ターミナル

> mkdir views

このviewsディレクトリには、テンプレートのファイルを保存します。それでは以下のようにserver.jsも変更しましょう。

■server.js

const express = require('express');
const app = express();
const port = 3000;
app.use(express.urlencoded({ extended: true })); 
app.set('view engine', 'ejs'); 

app.get("/",(req,res) => {
    res.render('test.ejs',{ name:''});
})

app.post("/form",(req,res)=> {  
    res.render('test.ejs',{ name: req.body.name }); 
});

app.listen(port, () => {
    console.log('サーバが起動しました。');
});

上記の記述を簡単に説明すると、前述の通り、JavaScriptにはEJS以外にもテンプレートエンジンが存在する為、下記のコードでは、set()メソッドを使ってテンプレートエンジンにEJSを使用する旨の設定を行っています。

app.set('view engine', 'ejs'); 

またgetメソッド・postメソッドでは、render()メソッドを使用して「test.ejs」ファイルをテンプレートファイルとして展開しています。EJSでは特に指定がなければ、viewsフォルダをデフォルトで参照する為、第一引数に「test.ejs」と記述するだけで、実際にはviewsディレクトリの中のtest.ejsファイルを参照しています。

res.render('test.ejs',{ name:''});

では次に、viewsディレクトリの中にEJSのテンプレートファイルを作成しましょう。ファイルの拡張子に「ejs」を指定して、「test.ejs」ファイルを作成します。以下の内容をコピーして貼り付けましょう。

■test.ejs

<!DOCTYPE html>
<html lang="ja">
    <head></head>
    <body>
        <form action="/form" method="POST">
            <input type="text" name="name">
            <button type="submit">送信</button>
        </form>
        <p><%= name %></p>
    </body>
</html>

こちらも記述内容を見ていくと、<p>タグ内の<%= name %>といった記述が存在しています。この<%= %>は、JavaScriptのコードをテンプレート内に埋め込み、実行するために使用するEJSの特殊タグです。
特殊タグ内には変数nameが指定されており、フォーム送信後に入力された値がそのまま変数nameに代入され、ブラウザに表示されます。

それでは、実際にフォームから値を送信してみましょう。下記のように入力した値が、入力欄の下に表示されたら成功です。

また、EJS特有のタグは他にもあり、主要タグは以下のような種類があります。

主要タグ内容
<% %>JavaScriptのコードをテンプレート内に埋め込み、
実行するために使用されます。
<%= %>埋め込んだ変数の値がエスケープ込みで展開される
<%- %>埋め込んだ変数の値がエスケープなしで展開される
<%# %>コメント扱いになり、HTMLとしては出力されない

※エスケープとは、プログラム内で特別な意味を持つ文字や記号を「ただの文字列」として扱いたい場合に行う処理です。特定の文字列や記号には、プログラム内で特別な意味が割り当てられている場合があり、例えばHTMLでは「<」や>がタグとして解釈され、SQLではシングルクオート(')が文字列の区切りとして扱われます。エスケープを使用することで、これらの特殊な文字を「ただの文字」として扱うことが可能となり、安全で正確なデータ処理や表示が実現できます。

本試験では、これらのEJSの主要タグについて、どのような種類があるかなどが問われるかなと思います!本章では内容が多く、実行結果について一例のみを紹介しましたが、その他の主要タグについても、ご自身でコードを書いて結果を確認してみましょう!

セキュリティについて

インターネットを通じて、Webアプリケーションやサービスを利用すると、Webサイト上での脆弱性を利用した攻撃に脅かされる可能性があります。本項目ではインターネット上での代表的な攻撃である「XSS」と「CSRF」の特徴ついて、詳しく説明を行います。

XSSについて

XSS(クロスサイトスクリプティング)とは、Webアプリケーションのセキュリティ上の脆弱性の一種で、攻撃者が悪意のあるスクリプトを埋め込むことで、他のユーザーにその悪意のあるコードを実行させることができるサイバー攻撃です。

XSS攻撃の危険性は、攻撃者がユーザーのセッション情報や個人情報を盗み出したり、不正な操作を行ったりすることができる点にあります。
簡単に例で説明しますと、攻撃者がホームページなどに実行させたいJavaScriptのコードを書き込み、他のユーザーがそのホームページを読み込んだ際などにJavaScriptが実行され、ページを読み込んだユーザのパソコンや、ホームページが表示されているサーバーなどが攻撃されるようになります。

たとえば、セキュリティ対策を行っていない掲示板に「こんにちは」と投稿する代わりに「<script>alert(“Hello!”);</script>」と入力して投稿を保存した場合、他のユーザーが掲示板を閲覧した際に、スクリプトが実行され「Hello!」というアラートが表示されてしまいます。
この程度では大きな被害はないかもしれませんが、攻撃者が悪意のあるスクリプトを埋め込むことで、重大な被害をもたらす可能性があります。

対策としては、先ほど紹介したエスケープ処理を適切に行う事などが重要となってきます。

CSRFについて

CSRF(クロスサイトリクエストフォージェリ)とは、ユーザーが認証済みの状態で、攻撃者が意図的に悪意のあるリクエストを送信させるサイバー攻撃です。先ほどのXSSと仕組みは似てますが、CSRFの特徴としては、ユーザーのアクセス権限を持って攻撃するという点になります。

例えば、オンライン銀行のサイトに攻撃者が罠を設置し、ユーザーがその罠にアクセスすると、ユーザーのアクセス権限を悪用され、攻撃者に送金する不正なリクエストが実行される可能性があります。このような場合、リクエストが認証されると、ユーザーの財産に被害が及ぶ恐れがあります。

他には、SNSや掲示板などで意図していない情報発信をされたり、その内容が誹謗中傷だった場合であれば知らない間に加害者という立場になっている可能性もあります。

簡単にできる対策としては、現代で知名度のあるフレームワークやライブラリを利用することです。CSRFは昔からある攻撃ですが、近年のフレームワークやライブラリには最初からCSRF対策が施されている為、利用できる場合は必ず利用して、正しく設定することが重要です。その他の対策としては、トークンの利用や、Referチェックなどが有効となります。
※フレームワークとは、システム開発においてよく利用される機能をあらかじめ用意した枠組みや構造を提供するツールとなります。フレームワークを利用することで効率的に開発を行うことができます。

本章では、Expressの導入からテンプレートエンジンの使用、更にはセキュリティについての内容までと幅広く学習してきました。特にコードを各箇所では、実際にご自身で記述を行って学習をしないと、身に着けるのは大変かと思います。最後まであきらめず、知識が定着するまで繰り返し学習していきましょう。

それでは、今回はここまで〜。

PAGE TOP