Node.js入門⑤ルーティングの基本をマスターしよう

Node.js

前回の記事でEJSを使ってindex.ejsをレンダリングして表示するということを勉強しました

しかし、前回のやり方だとサーバーにアクセスしたら必ずindex.htmlしか表示されません

CSSファイルすら別にすることができませんでした

そこで、今回はクライアントがアクセスしたアドレスによって表示する内容を変えるということ

「ルーティング」について勉強していきましょう

ルーティングとは

我々がWebページにアクセスする際は、その知りたい情報によってアドレスをかえてサーバーにアクセスしています

/

こんにちは。

Kikuchannelへようこそ。

/about

Kikuchannelはプログラミングの勉強のためのチャンネルです。

といったように、クライアントがアクセスしたアドレスによってサーバーはどういったコンテンツを表示するか定義しなければなりません

URLによって表示を分岐する必要があります

URLモジュールを利用する

URLを利用するには、サーバーがURLを見てアドレスを知る必要があります

URLには決まった書き方がありますが、それを解析して処理を分岐する必要があります

それを簡単に処理するためのモジュールがURLモジュールです

次はURLモジュールの説明をするためのサンプルコードです

※url.parseは非推奨とでると思います。現在はWHATWG URL APIを使用するようにと表示されていましたのでそのコードもサンプルとしてこのページの下のほうに置いておきます。よかったら参考にしてください。YouTubeのはめ込み動画の下にあります。

const url = require('url');
const my_url = "http://localhost:3000/user?country=Japan&city=Tokyo";
const url_Object = url.parse(my_url,true);
console.log(url_Object.host);
console.log(url_Object.pathname);
console.log(url_Object.search);
const queryData = url_Object.query
console.log(queryData.country);
console.log(queryData.city);
view raw URL module hosted with ❤ by GitHub

これを実行すると、URLモジュールによってURLからどのような情報が解析されているかがよくわかると思います

2行目で適当なlocalhost:3000のURLを書いていますが

実行した結果がこちらです

ホスト名:localhost:3000

pathname:/user

query:?country=Japan&city=Tokyo

queryのcontry:Japan

queryのcity:Tokyo

と、URLがバラバラにされて解析されているのがわかると思います

これをパース処理とよびます

URLモジュールをつかうことで簡単にURLをパース処理して、パス名を抽出したり

query(クエリ)を抽出したりすることができるのです

ちなみに、queryはご存じですか?

queryとは

サーバーへ受け渡すためのデータをURLの末尾に付け加えることができます。

?名前=値 

の形でURLの末尾に記述します。

複数のデータがある場合は&をつかって複数個記述します。

これによってサーバーへデータを送ることができるようになります。

requestのURLによって処理を分岐させる

あとは、URLによって処理を分岐するだけです

以下が今回のサンプルコードです

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=title%></title>
<link type="text/css" href="./style.css" rel="stylesheet">
</head>
<body>
<header>
<h1><%=title%></h1>
</header>
<div role="main">
<p>This is Kikuchannel.</p>
<p>こんにちは、今日は<%=today%>です。</br> 今日も一日がんばろう!</p>
</div>
</body>
view raw index.ejs hosted with ❤ by GitHub
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const moment = require('moment');
const url = require('url');
moment.locale('ja');
let datetoday = moment().format('LL');
const index = fs.readFileSync('./index.ejs','utf8');
const sample = fs.readFileSync('./sample.ejs','utf8');
const style_css =fs.readFileSync('./style.css','utf8');
var server = http.createServer(getFromClient);
server.listen(3000);
console.log('Server start!');
console.log(datetoday);
function getFromClient(req,res){
var url_parts = url.parse(req.url);
console.log(url_parts)
switch(url_parts.pathname){
case '/':
var content = ejs.render(index,{
title:'Kikuchannel',
today:datetoday,
});
res.writeHead(200, {'Content-Type':'text/html'});
res.write(content);
res.end();
break;
case '/sample':
var content = ejs.render(sample,{
title:'introduction',
today:datetoday,
});
res.writeHead(200, {'Content-Type':'text/html'});
res.write(content);
res.end();
break;
case '/style.css':
res.writeHead(200, {'Content-Type':'text/css'});
res.write(style_css);
res.end();
break;
default:
res.writeHead(404, {'Content-Type':'text/plain'});
res.end('no page...');
break;
}
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=title%></title>
<link type="text/css" href="./style.css" rel="stylesheet">
</head>
<body>
<header>
<h1><%=title%></h1>
</header>
<div role="main">
<p>I'm Kiku.</p>
<p>こんにちは、今日は<%=today%>です。</br> 今日も一日がんばろう!</p>
</div>
</body>
view raw sample.ejs hosted with ❤ by GitHub
header h1 {
font-size: 60pt;
background-color: darkcyan;
color: #eee;
text-align: left;
margin: 50px;
}
body {
font-size: 14pt;
color: #999;
margin: 5px;
}
view raw stylesheet.css hosted with ❤ by GitHub

上からindex.ejs、app.js、sample.ejs、stylesheet.cssです

サーバーにアクセスしたときの処理をする関数がapp.jsの

function getFromClient(req,res){…}

の部分です

このreqの部分にURLが入っています

それをURLモジュールでパース処理しています

var url_parts = url.parse(req.url); その内容をオブジェクト型の配列で変数に格納しています

パス名によって分岐をしますので

switch(url_parts.pathname){分岐処理}

switchを使い条件分岐をしています

パス名によってレンダリングするファイルを変更しています

CSSファイルもこうすることで読み込まれて反映されています

実は、この処理をしないとCSSファイルをリンクさせてもアクセスしないので、CSSは反映されません

今回はURLモジュールを使ったルーティングの基礎を勉強しました

YouTubeもよろしくお願いします!

※url.parseは非推奨とでると思います。現在はWHATWG URL APIを使用するようにと表示されていましたのでそのコードもサンプルとしてここに置いておきます。よかったら参考にしてください。

const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const moment = require('moment');
moment.locale('ja');
let datetoday = moment().format('LL');
const index = fs.readFileSync('./index.ejs','utf8');
const sample = fs.readFileSync('./sample.ejs','utf8');
const style_css =fs.readFileSync('./style.css','utf8');
var server = http.createServer(getFromClient);
server.listen(3000);
console.log('Server start!');
console.log(datetoday);
function getFromClient(req,res){
var url_parts = new URL(req.url,'http://localhost:3000');
console.log(url_parts)
switch(url_parts.pathname){
case '/':
var content = ejs.render(index,{
title:'Kikuchannel',
today:datetoday,
});
res.writeHead(200, {'Content-Type':'text/html'});
res.write(content);
res.end();
break;
case '/sample':
var content = ejs.render(sample,{
title:'introduction',
today:datetoday,
});
res.writeHead(200, {'Content-Type':'text/html'});
res.write(content);
res.end();
break;
case '/style.css':
res.writeHead(200, {'Content-Type':'text/css'});
res.write(style_css);
res.end();
break;
default:
res.writeHead(404, {'Content-Type':'text/plain'});
res.end('no page...');
break;
}
}
view raw app.js hosted with ❤ by GitHub
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=title%></title>
<link type="text/css" href="./style.css" rel="stylesheet">
</head>
<body>
<header>
<h1><%=title%></h1>
</header>
<div role="main">
<p>This is Kikuchannel.</p>
<p>こんにちは、今日は<%=today%>です。</br> 今日も一日がんばろう!</p>
</div>
</body>
view raw index.ejs hosted with ❤ by GitHub
{
"name": "samplecode",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.6",
"moment": "^2.29.1"
}
}
view raw package.json hosted with ❤ by GitHub
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=title%></title>
<link type="text/css" href="./style.css" rel="stylesheet">
</head>
<body>
<header>
<h1><%=title%></h1>
</header>
<div role="main">
<p>I'm Kiku.</p>
<p>こんにちは、今日は<%=today%>です。</br> 今日も一日がんばろう!</p>
</div>
</body>
view raw sample.ejs hosted with ❤ by GitHub
header h1 {
font-size: 60pt;
background-color: darkcyan;
color: #eee;
text-align: left;
margin: 50px;
}
body {
font-size: 14pt;
color: #999;
margin: 5px;
}
view raw style.css hosted with ❤ by GitHub

動画も作りましたのでこちらもぜひ参考になさってください。

コメント

  1. HNaito より:

    app.jsを実行してからブラウザに「loaclhost:3000」を入力して、下記の一つ目のUrlオブジェクトが表示されるのは理解できるのですが、二つ目のUrlオブジェクトが表示されるのはなぜでしょうか。

    Url {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: ‘/’,
    path: ‘/’,
    href: ‘/’
    }
    Url {
    protocol: null,
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: null,
    search: null,
    query: null,
    pathname: ‘/style.css’,
    path: ‘/style.css’,
    href: ‘/style.css’
    }

    • Kikujiro より:

      こんばんは。
      自分の書いているindex.ejsのコードを見ていただくと、7行目にlink type=”text/css” href=”./style.css” rel=”stylesheet”とあるんですが、ここでcssファイルを読み込んでいるから、/style.cssが二つ目のURLオブジェクトに表示されています。
      要するに
      ①localhost:3000にアクセスする path”/”
      ②index.ejsがレンダリングされる
      ③style.cssが読み込まれる path”/style.css”
      という流れです。
      index.ejsのコードの7行目を消してみると2つ目のURLオブジェクトは読み込まれないため、ログには表れないはずです。よろしければ一度試してみてください(一応自分も確かめてみました笑)。

      • HNaito より:

        ご回答ありがとうございました。

        という文で、どういう処理がおこなわれるのか具体的につかめました。

        今後ともよろしくお願いいたします。

        • HNaito より:

          先ほどの文中で、下記の文を〈〉で囲ったら表示されなくなってしまったようです。

          link type=”text/css” href=”./style.css” rel=”stylesheet”

PAGE TOP
タイトルとURLをコピーしました