クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Node.js】ルーティング設定で複数ページを表示する

Node.jsの続きです。前回はルーティング設定でCSS、JSのファイルを読み込みました。今回は同じくルーティング設定で複数のHTMLページを表示をしてみました。やってみて結構URLの表示判定が厳密なこともわかりました。それでは行きましょう!

【目次】

前回記事
※参考:【Node.js】ルーティング設定でCSS、JSファイルを読み込む - クモのようにコツコツと

Node.js / Expressを習得するためにやったことまとめ(随時更新)
qiita.com

前回のおさらい

ブラウザを開くと、お、JSでアラートが立ち上り f:id:idr_zz:20200330202233j:plain

CSSスタイルで見出しが赤くなる f:id:idr_zz:20200330202257j:plain

HTMLコード

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
        <title>こんにちは、のおど・じぇいえす。</title>
        <!--link rel="stylesheet" href="css/style.css">
        <script src="js/script.js"></script-->
    </head>
<body>
    <section>
        <h1>こんにちは、のおど・じぇいえす。</h1>
        <p>Node.jsでHTMLタグを作れるのかテストですと。</p>
    </section>
</body>
</html>

JSコード

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

const indexPage = fs.readFileSync('./html/index.html', 'UTF-8');
const otherPage = fs.readFileSync('./html/other.html', 'UTF-8');
const styleCss = fs.readFileSync('./html/css/style.css', 'UTF-8');
const scriptJs = fs.readFileSync('./html/js/script.js', 'UTF-8');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer(RouteSetting);

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

function RouteSetting(req, res) {
  const url_parts = url.parse(req.url);
  switch (url_parts.pathname) {
    case '/':
    case '/index.html':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(indexPage);
      res.end();
      break;
  
    case '/css/style.css':
    res.writeHead(200, {'Content-Type': 'text/css'});
    res.write(styleCss);
    res.end();
    break;

    case '/js/script.js':
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write(scriptJs);
      res.end();
      break;

    default:
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('お探しのページは見つかりません。');
      break;
  }
}

詳細は前回記事を参照
※参考:【Node.js】ルーティング設定でCSS、JSファイルを読み込む - クモのようにコツコツと

今回も掌田さんの「Node.js超入門」を参考に進める。

Node.js超入門[第2版]

Node.js超入門[第2版]

他のページを追加する

複数のページを表示するためにhtmlファイルを増やす。

前回のファイル構成

node_test
├html
│├css
││└style.css
│├js
││└script.js
│├index.html
└node_test.js
  • 外側のnode_test.jsはNode.jsの設定ファイル
  • htmlフォルダの中にページのファイルがある
  • さらにcssとjsのフォルダ、ファイルもある。

htmlファイルをさらに増やす。

node_test
├html
│├css
││└style.css
│├js
││└script.js
│├index.html
│├other.html(新規)
│└sub(新規)
││└index.html(新規)
└node_test.js
  • トップページと同じ階層に「othet.html」を増やす(別ページ)
  • 「sub」フォルダを作り「index.html」を増やす(下層ページ)

トップページに他のページのリンクを追加

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
        <title>こんにちは、のおど・じぇいえす。</title>
        <link rel="stylesheet" href="css/style.css">
        <script src="js/script.js"></script>
    </head>
<body>
    <section>
        <h1>こんにちは、のおど・じぇいえす。</h1>
        <p>Node.jsでHTMLタグを作れるのかテストですと。</p>
        <p><a href="other.html">別ページへ</a></p>
        <p><a href="sub/">下層ページへ</a></p>
        <p><a href="hoge.html">架空のページへ</a></p>
    </section>
</body>
</html>
  • aタグで同一階層の「other.html」へのリンク追加
  • aタグで下層階層の「sub」へのリンク追加
  • aタグで架空ページの「hoge.html」へのリンク追加

架空ページは存在しないURLの動きを見たくて追加した。

同一階層別ページ「other.html」の作成

同一階層の別ページ「other.html」を書く。

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
        <title>別のぺえじ</title>
        <link rel="stylesheet" href="css/style.css">
        <script src="js/script.js"></script>
    </head>
<body>
    <section>
        <h1>ここは別のページです</h1>
        <p>Node.jsで複数ページを作るテスト。</p>
        <p><a href="/index.html">TOPページへ</a></p>
    </section>
</body>
</html>
  • CSS、JSファイルのリンクはTOPページと共通
  • TOPページに戻るリンクがある

下層ページ「sub/index.html」を作成

次に下層ページ「sub」フォルダの中の「index.html」を書く。

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
        <title>下層ぺえじ</title>
        <link rel="stylesheet" href="../css/style.css">
        <script src="../js/script.js"></script>
    </head>
<body>
    <section>
        <h1>ここは下層ページです</h1>
        <p>Node.jsで複数ページを作るテスト。</p>
        <p><a href="../index.html">TOPページへ</a></p>
    </section>
</body>
</html>
  • 「other.html」と同じ構成だがリンクは「../」にしている

CSSファイル、JSファイル、TOPページへのリンクをそれぞれ上の階層を意味する「../」付きにする。

※参考:【HTMLの基本】書ける前に読む!HTML、CSS、JSの書式-2 - クモのようにコツコツと

Node.jsにページのルーティング設定を追加

node.jsの設定ファイル「node_test.js」に追加したページのルーティング設定を追記。

まずfsモジュールでファイルを読み込む

const indexPage = fs.readFileSync('./html/index.html', 'UTF-8');
const otherPage = fs.readFileSync('./html/other.html', 'UTF-8');
const subPage = fs.readFileSync('./html/sub/index.html', 'UTF-8');
const styleCss = fs.readFileSync('./html/css/style.css', 'UTF-8');
const scriptJs = fs.readFileSync('./html/js/script.js', 'UTF-8');
  • 変数otherPagefs.readFileSync()other.html'を読み込む
  • 変数subPagefs.readFileSync()/sub/index.html'を読み込む

次に別ページ「other.html」のルーティング設定

    case '/other.html':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(otherPage);
      res.end();
      break;

caseの条件のファイル名を/other.htmlにしたのみ。

下層ページ「/sub/index.html」のルーティング設定

    case '/sub/':
    case '/sub/index.html':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(subPage);
      res.end();
      break;

こちらはTOPページと同様にindex.htmlの有無を両方有効にしたいので条件を「/sub/」と「/sub/index.html」2つにした。

最後に架空のページを書き換え。

    default:
      res.setHeader('Content-Type', 'text/plain; charset=utf-8');
      res.write('お探しのページは見つかりません。');
      res.end();
      break;

前回の書き方だと日本語が文字化けることがわかったので、以前の「日本語化」の時と同じように書き変えた。

※参考:【Node.js】ハローワールドの打ち替え(ポート番号、日本語化、HTMLタグ化) - クモのようにコツコツと

ページの表示を確認

実際にページが表示されるか確認する。

まずターミナルのcdコマンドでフォルダに移動

cd (ファイルパス)/node_test

Node.jsサーバを起動!

node node_test.js

サーバが起動成功のコンソールログが帰ってくる。

Server running at http://127.0.0.1:3000/

ブラウザでURLを開く

http://127.0.0.1:3000/

JSが動いてアラートが立ち上がる(以後、他のページもアラートが立ち上がるが省略します) f:id:idr_zz:20200330202233j:plain

TOPページが表示される f:id:idr_zz:20200403054044j:plain 先程追加した「別ページ」「下層ページ」「架空ページ」のリンクが追加されている。

追加したページを表示してみる

追加したページに行ってみよう!

別ページ

最初に「別ページ」!リンクはother.html

<p><a href="other.html">別ページへ</a></p>

このURLになる。

http://127.0.0.1:3000/other.html

ページは表示された! f:id:idr_zz:20200403054408j:plain

下層ページ

TOPページに戻って、次は「下層ページ」。リンクはsub/

<p><a href="sub/">下層ページへ</a></p>

このURLになる。

http://127.0.0.1:3000/sub/

下層ページも表示された! f:id:idr_zz:20200403054911j:plain

架空ページ

最後、架空のページ。リンクはhoge.html

<p><a href="hoge.html">架空のページへ</a></p>

このURLになる。

http://127.0.0.1:3000/hoge.html

switch文のdefault条件に書いたテキスト「お探しのページは見つかりません。」が表示された! f:id:idr_zz:20200403055125j:plain

リンクの打ち替え(index.htmlの有無、スラッシュの有無、クエリパラメータ)

下層ページのところでURLをいくつか打ち替えてみる。

index.htmlを追記(成功)

まず、index.htmlを追記する。ルーティングに設定したので行けるはず。

http://127.0.0.1:3000/sub/index.html

結果、いけた!
f:id:idr_zz:20200403054911j:plain

拡張子をhtmにしてみる

そういえばたまにhtmという拡張子を見かける?と思い出してやってみる。

http://127.0.0.1:3000/sub/index.htm

結果、見つかりません。。
f:id:idr_zz:20200403055125j:plain

※参考:html と htm の違い - 違いがわからん!

そもそも別ファイルなんだね。でもルーティング設定しちゃえば共通化もできるか。

スラッシュを削除

下層フォルダの最後のスラッシュを削除してみる。

http://127.0.0.1:3000/sub

結果、見つかりません。。
f:id:idr_zz:20200403055125j:plain
うわー、思ったより厳密なんだなー。

他のサイトの例を見ると転送設定でスラッシュありにしている例もあった。

例えば下記のリンクを開くとアップルのiPhoneページが開く。

※参考:iPhone - Apple(日本)

URLはスラッシュなしにしている

https://www.apple.com/jp/iphone

しかし実際に開くページはスラッシュありになる

https://www.apple.com/jp/iphone/

ルーティング設定より転送設定の方が楽なのかもしれない。アクセスさせたいURLを一本化させる狙いもある?

パラメータを追加

最後、パラメータを追加してみる。 クエリパラメータとはURLの最後に?hoge=fugaとか追加するやつ。

※参考:【JS】フォームのinputタグにURLパラメータを渡す方法 - クモのようにコツコツと

http://127.0.0.1:3000/sub/?hoge=fuga

結果、パラメータは問題なく表示されるようだ。
f:id:idr_zz:20200403054911j:plain

念のためindex.html付きでもやってみる。

http://127.0.0.1:3000/sub/index.html?hoge=fuga

うむ。問題なし。
f:id:idr_zz:20200403054911j:plain

コード全体

最終的にこうなった。

JSコード

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

const indexPage = fs.readFileSync('./html/index.html', 'UTF-8');
const otherPage = fs.readFileSync('./html/other.html', 'UTF-8');
const subPage = fs.readFileSync('./html/sub/index.html', 'UTF-8');
const styleCss = fs.readFileSync('./html/css/style.css', 'UTF-8');
const scriptJs = fs.readFileSync('./html/js/script.js', 'UTF-8');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer(RouteSetting);

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

function RouteSetting(req, res) {
  const url_parts = url.parse(req.url);
  switch (url_parts.pathname) {
    case '/':
    case '/index.html':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(indexPage);
      res.end();
      break;
  
    case '/other.html':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(otherPage);
      res.end();
      break;

    case '/sub/':
    case '/sub/index.html':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write(subPage);
      res.end();
      break;
    
    case '/css/style.css':
      res.writeHead(200, {'Content-Type': 'text/css'});
      res.write(styleCss);
      res.end();
      break;

    case '/js/script.js':
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write(scriptJs);
      res.end();
      break;

    default:
      res.setHeader('Content-Type', 'text/plain; charset=utf-8');
      res.write('お探しのページは見つかりません。');
      res.end();
      break;
  }
}

最後に

ということで、ルーティング設定で複数のページを表示しました。パラメータは気にせず付けていいことがわかりましたが、URLは最初に想定しておかないと少しでも合わないと「見つかりません」になる。他のサイトを見ると転送設定で解決している例もありました。ここらへんのURL設計は最初によく考えておくべきかなと。

こうした処理を全部ネイティブのNode.jsだけで書いていくのもだんだん辛さを感じてきたので、そろそろExpressに入ろうかという気持ちになってきました。。

それではまた!


Node.js / Expressを習得するためにやったことまとめ(随時更新)
qiita.com