前回の最後にちょっとだけやりましたが、エックスサーバーでNode.jsを動かしてみることにします。⇒ 動作確認はこちら。あまりにしょぼすぎるサイトです。
ここではテンプレートエンジンのひとつであるEJSを使用しています。SSH接続をしたら適当なディレクトリを作成して、そこにnpmでEJSをインストールします。
index.ejsを用意する
npmでEJSをインストールしたらindex.ejsというファイルを作成してアップロードします。
index.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <title><%-page_title%></title> <link rel="stylesheet" href="./style.css" media="all"> </head> <body> <div id = "container"> <div id="header"> <h1><a href="./"><%-site_title%></a></h1> </div> <div id="main"> <h2><%-page_title%></h2> <%-main_content%> </div> <div id="sidebar"> <h2>その他の記事</h2> <ul> <%-sidebar_link%> </ul> </div> <br clear="all"> </div> </body> </html> |
style.cssを作成する
index.ejsを作成したらスタイルシートを使うので以下のファイルも作成します。
style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
body { font-size: 14pt; color: #333; } #container { width: 1000px; margin:0px auto 0px auto; padding: 0px; min-height: 600px; } #header h1 { font-size: 48pt; background-color: darkcyan; color: #eee; text-align: center; margin:0px; padding: 30px; } #header a{ color: #eee; text-decoration:none; } #header a:hover { color: #fff; text-decoration:underline; } h2 { color: #000000; } #main { float:left; width:60%; padding: 0px 30px 0 30px; } #sidebar { float:right; width:30%; padding: 0px 10px 0 10px; } #sidebar h2{ text-align: center; } #sidebar li{ margin: 0px 0px 10px 0px; list-style: none; } #sidebar a:hover { color: #f00; font-weight:bold; } .red { color: #f00; } @media screen and (max-width: 1000px) { #container { width: 100%; } #main { padding: 0px; } #sidebar { padding: 0px; } } @media screen and (max-width: 600px) { #main { width: 100%; padding: 0px; float: none; } #sidebar { width: 100%; float: none; } } |
app.jsの作成
次にapp.jsを作成します。http、fs、ejsをrequireします。ポートは前回65000を使用したので今回は65001を使います。そのあと「url」オブジェクトによるURL処理をおこないます。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
const http = require('http'); const fs = require('fs'); const ejs = require('ejs'); const port = 65001; const index = fs.readFileSync('./index.ejs','utf8'); const style = fs.readFileSync('./style.css','utf8'); const baseUrl = 'https://lets-csharp.com/samples/2108/nodejs-test2'; let server = http.createServer(getFromClient); server.listen(port); console.log('Server start!'); function getFromClient(req,res){ let obj = { site_title: 'Node.jsのテスト', page_title: '', main_content : '', sidebar_link : getSidebarLinkString(), }; let url_parts = new URL(req.url, baseUrl); if(url_parts.pathname == '/' || url_parts.pathname == '/index.html') getFromClientIndex(res, obj); else if(url_parts.pathname == '/001.html') getFromClient001(res, obj); else if(url_parts.pathname == '/style.css') getFromClientStyle(res, obj); else getFromClient404(res, obj, url_parts.pathname); } |
あとはそれぞれのページのリクエストの処理をするだけです。
ejs.render関数に渡すオブジェクトにはsite_title、page_title、main_content、sidebar_linkがあります。site_titleは同じものを使うのでgetFromClient関数のなかで設定しています。sidebar_linkも同じものを使うので、getSidebarLinkString関数のなかで文字列を取得して、これを設定しています。
|
// ejs.render関数に渡すオブジェクト let obj = { site_title: 'Node.jsのテスト', page_title: '', // 各関数内で設定する main_content : '', // 各関数内で設定する sidebar_link : getSidebarLinkString(), }; |
トップページのレンダリング
トップページの場合はgetFromClientIndex関数のなかで、page_titleを’Node.jsのテストで作成したページ’に設定して、main_contentに設定する文字列を作成します。現在時刻や乱数を使って今日の運勢を占っています。時刻によってあいさつの言葉も変えています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
function getFromClientIndex(res, obj){ obj.page_title = 'Node.jsのテストで作成したページ'; // main_contentに設定する文字列 let str1 = '<p>ここはトップページです。</p>'; let str2 = '<p>Node.jsのテストのために作成したサイトです。</p>'; // 現在時刻を表示させる let date = new Date(); let howr = date.getHours(); let minute = date.getMinutes(); let second = date.getSeconds(); // 現在時刻であいさつの言葉を変える let aisatsu = ''; if(howr < 4) // 深夜 aisatsu = 'こんばんは。'; else if(howr < 12) // 早朝または午前中 aisatsu = 'おはようございます。'; else if(howr < 18) // 午後 aisatsu = 'こんにちは。'; else // 夕方以降 aisatsu = 'こんばんは。'; let ganbarou = '今日も一日頑張ろう!'; if(howr > 18) // 夕方以降に'今日も一日頑張ろう!'はおかしいので明日にしている anbarou = 'おつかれさま。明日も頑張ろう。'; // 現在時刻を表示 let str3 = '<p>' + aisatsu + '現在時刻は <strong>' + howr + '時' + minute + '分' + second + '秒</strong> です。' +ganbarou + '</p>'; // 今日の運勢(18時以降は明日の運勢) let str40 = ''; if(howr < 18) str40 = '今日のあなたの運勢は <strong class = "red">' + FortuneTelling() + '</strong> です。'; else str40 = '明日のあなたの運勢は<strong>' + FortuneTelling() + '</strong>です。'; let str4 = '<p>' + str40 + '運勢が気に入らないときは F5 キーを押してください。</p>'; // あとはレンダリングするだけ let str = str1 + str2 +str3 + str4; obj.main_content = str; let content = ejs.render(index, obj); res.writeHead(200, {'Content-Type':'text/html'}); res.write(content); res.end(); } // 今日の運勢を占う function FortuneTelling(){ let rand = Math.random(); if(rand < 0.1) return '大吉' else if(rand < 0.5) return '中吉' else if(rand < 0.9) return '小吉' else if(rand < 0.95) return '凶' else return '大凶' } |
getSidebarLinkString関数はサイドバーに表示させる他のページへのリンクの文字列を生成・取得します。
|
function getSidebarLinkString(){ let str1 = '<li><a href="./">トップページへ</a></li>\n'; let str2 = '<li><a href="./001.html">最初のページへ</a></li>\n'; let str3 = '<li><a href="./404.html">存在しないページ</a></li>\n'; return str1 + str2 + str3; } |
スタイルシートのCSSファイルも同じディレクトリ内に置くので、getFromClientStyle関数でその内容を取得できるようにします。このような処理をしないと単にファイルをアップロードするだけでは認識されません。
|
function getFromClientStyle(res, obj){ let content = ejs.render(style); res.writeHead(200, {'Content-Type':'text/css'}); res.write(content); res.end(); } |
他のページのレンダリング
/001.htmlにアクセスしたときのレンダリングの処理を示します。「ここは/001.htmlです」と表示させるだけです。
|
function getFromClient001(res, obj){ obj.page_title = '1ページ目'; obj.main_content = '<p>ここは/001.htmlです。</p>'; let content = ejs.render(index, obj); res.writeHead(200, {'Content-Type':'text/html'}); res.write(content); res.end(); } |
存在しないページにアクセスしたら「○○は存在しないページです」と表示させるとともにトップページに戻るためのリンクも表示させます。トップページと001.html、style.css以外は存在しないものとして処理をします。
|
function getFromClient404(res, obj, url){ obj.page_title = '存在しないページ'; obj.main_content = '「' + url + '」は存在しないページです。<a href="./">Topページへ戻る</a>'; let content = ejs.render(index, obj); res.writeHead(200, {'Content-Type':'text/html'}); res.write(content); res.end(); } |
https://lets-csharp.com/samples/2108/nodejs-test2/にアクセスしたときにサイトを表示させたいので/home/{サーバーID}/lets-csharp.com/public_html/samples/2108/nodejs-test2/に以下の.htaccessをアップロードします。
.htaccess
|
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)$ http://localhost:65001/$1 [P,L] </IfModule> |
SSH接続してapp.jsをアップロードしたディレクトリに移動し、以下のコマンドを入力すればサイトが表示されます。
|
node app.js & # 上を実行したらCtrl + Cを押す。そのあと disown |
鳩でも分かるC#管理人からのお願い
できる仕事であれば請け負います。鳩でもわかるC#管理人はクラウドワークスに在宅ワーカーとして登録しています。お仕事の依頼もお待ちしております。
⇒ 仕事を依頼する
コメントについて
コメントで英語などの外国語でコメントをされる方がいますが、管理人は日本語以外はわからないので基本的に内容が理解できず、承認することもありません。それからへんな薬を売っているサイトやリンク先のサイトが存在しないというスパムコメントも多々あります。
Some people make comments in foreign languages such as English, but since the manager does not understand anything other than Japanese, he basically cannot understand the content and does not approve it. Please use Japanese when making comments.
そんななか日本語のコメントもいただけるようになりました。「○○という変数はどこで宣言されているのか?」「××というメソッドはどこにあるのか」「例外が発生する」「いっそのことソース丸ごとくれ」という質問ですが、管理人としては嬉しく思います。「自分が書いた記事は読まれているんだな」と。疑問点には可能な限り答えます。記事に問題があれば修正いたします。
そのうえでお願いがあります。「匿名」という味も素っ気もない名前ではなく、捨てハンでいいのでなにかハンドルネームをつくってほしいと思います。
管理人のモチベーションアップのために
よろしければご支援お願いします。
⇒ 管理人の物乞いリスト
とても参考になる記事ありがとうございます!
同じような構成でサイト構築を考えていたのですが、
一点とても気になっていることがあり、コメント(質問)失礼します。
https://lets-csharp.com/samples/2108/nodejs-test2/
上記の動作確認用のサイトはSSL化されているのですが、
エックスサーバーでこんなことができるのだととても衝撃でした!
こちらはなにかしら設定が必要かと思いますが、
エックスサーバーの無料独自SSL(Let’s Encrypt)を利用しているカタチになりますでしょうか?
ご教授いただけますと幸いです。
ワードプレスでサイトを立ち上げ、その際に以下の方法で無料独自SSL設定をしています。
Webサイトの常時SSL化
https://www.xserver.ne.jp/manual/man_server_fullssl.php
そのなかでディレクトリをつくってそこで公開しているのでその他のWebアプリでもSSLの設定は引き継がれます。
鳩でもわかるC#管理人 様
ありがとうございます!
世界が広がりました!
さっそく挑戦したいと思います!
本当にありがとうございます!