の続きです。
http通信
const http = require('http');
const server = http.createServer((req,res)=>{
res.write('Hello world from nodejs');
res.end();
});
server.listen('3000');
node app
でこれを実行し、ブラウザ(chromeやedgeなど)のurl検索欄で
localhost:3000
と検索すると、ブラウザに次の画面が表示されます。
なお、app.jsはずっと実行しっぱなしになっていると思うので、終わったらctrl+cで中断しておきます(以下の操作でも同様)。
htmlファイルの表示
app.jsと同じディレクトリにstaticというフォルダを用意して、次のhtmlファイルを入れます:
Test HTML file
実行するJavascriptファイルは次のものです:
const http = require('http');
const fs = require('fs');
http.createServer((req,res)=>{
//output html file
const readStream = fs.createReadStream('./static/index.html');
res.writeHead(200,{'Content-type':'text/html'});
readStream.pipe(res);
}).listen('3000');
実行してlocalhost:3000を更新すると、ブラウザに
と表示されます。
フレームワークexpressの利用
コマンドプロンプトで
npm init --yes
npm install express
と打ち込んで、フレームワークの1つであるexpressパッケージをインストールします。以下、このフレームワークを使います。
Javascriptファイルに
const express = require('express');
と書けば、このobjectにexpressの中身が入っています。
get通信(urlから変数を読み込む)
const express = require('express');
const app = express();
app.get('/',(req,res)=>{
res.send('Hello World');
});
app.get('/example',(req,res)=>{
res.send('hitting example route');
});
// :name & :age in url are read as req.params
//?xxx = yyy&zzz=www in url is pushed into req.query by json style
app.get('/example/:name/:age',(req,res)=>{
console.log(req.params); //読み込んだパラメーターをターミナルに表示
console.log(req.query); //読み込んだクエリをターミナルに表示
res.send(req.params.name + " : " + req.params.age);
});
app.listen(3000);
実行して、ブラウザで、例えば
localhost:3000
と検索すると、
localhost:3000/example
と検索すると
とブラウザに表示されます。
また、
localhost:3000/pedro/99
では、
となり、ターミナルには
{ name: 'predro', age: '99' }
と出力されます。最後に
http://localhost:3000/example/predro/99?tutorial=paramstutorial&sort=byage
で検索すると、ブラウザではひとつ前のものと同じ出力ですが、ターミナルでは
{ name: 'predro', age: '99' }
{ tutorial: 'paramstutorial', sort: 'byage' }
が出力されます。1行目はreq.params、2行目はreq.queryの中身です。
つまり:xxxの中身はreq.paramsに、?の後の等式はreq.queryにjson形式で格納されます。
htmlファイルの呼び出し
最初のhttp通信のセクションでつかったindex.htmlを使います。
const express = require('express');
const path = require('path')
const app = express();
app.use('/public',express.static(path.join(__dirname,'static')));
app.get('/',(req,res)=>{
res.sendFile(path.join(__dirname,'static','index.html'));
});
app.listen(3000);
localhost:3000
で検索すると、http通信のときと同じ画面が出力されます。
post通信(ユーザーが入力したものを読み込む)
パッケージの読み込み
コマンドプロンプトで
npm install body-parser
と打って、body-parserも読み込んでおきます。
htmlファイル
ユーザーが入力できるようなフォームを表示するようにstatic/index.htmlを書き直します。今回はメアドとパスワードを入力してもらいます。今回の話のメインはnode.jsなので、htmlの書き方については触れません。
<form action="/" method="POST">
<div clas="form-group">
<label for="email">Email adress:</label>
<input type="email" class="form-control" name="email">
</div>
<div clas="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" name="pasword">
</div>
<button type="submit" class="btn btn-default"> Submit</button>
</form>
API
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();
app.use('/public',express.static(path.join(__dirname,'static')));
app.use(bodyParser.urlencoded({extended:false}));
app.get('/',(req,res)=>{
res.sendFile(path.join(__dirname,'static','index.html'));
});
app.post('/',(req,res)=>{
console.log(req.body);
//database work here
res.send('successfully posted data');
});
app.listen(3000);
これを実行してlocalhost:3000を見ると以下のようなフォームが表示されます。
適当にメアドの欄にはaaa@gmail.com、パスワードの欄にはbbbbbbbbと打ちました。
次にsubmitボタンをクリックすると
と画面が切り替わり、以下のようにちゃんと入力した内容がreq.bodyとして読み込まれてターミナルに出力されています。
[Object: null prototype] {
email: 'aaa@gmail.com',
pasword: 'bbbbbbbb'
}
読み込んだ内容の条件判定
パッケージのインストール
npm install joi
API
index.htmlは先ほどのpost通信のものを使い、postで読み込んだデータが設定した条件を満たすか判定します。
const express = require('express');
const express = require('express');
const path = require('path');
const Joi = require('joi');
const bodyParser = require('body-parser');
const app = express();
app.use('/public',express.static(path.join(__dirname,'static')));
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.get('/',(req,res)=>{
res.sendFile(path.join(__dirname,'static','index.html'));
});
app.post('/',(req,res)=>{
console.log(req.body);
//set conditions of res.params
const schema = Joi.object().keys({
email : Joi.string().trim().email().required(),
password : Joi.string().min(5).max(10).required()
});
//check conditions
const validation = schema.validate(req.body);
if(validation.error){
console.log(validation.error);
res.send('an error has occurred');
}
else res.send('successfully posted data');
});
app.listen(3000);
実行したのち、localhost:3000のフォームで、
メアド:aaa@gmail.com
パスワード:bbbbbbbb
を入力してsubmitボタンを押すと
がブラウザに表示され、ターミナルでも
[Object: null prototype] {
email: 'aaa@gmail.com',
password: 'bbbbbbbb'
}
となっています。
一方、
メアド:aaa@gmail.com
パスワード:c
としてsubmitボタンを押すと
がブラウザに表示され、ターミナルでは
[Error [ValidationError]: "password" length must be at least 5 characters long] {
_original: [Object: null prototype] { email: 'aaa@gmail.com', password: 'c' },
details: [
{
message: '"password" length must be at least 5 characters long',
path: [Array],
type: 'string.min',
context: [Object]
}
]
}
が出力されます。今回の条件はパスワードが5文字以上、10文字以下というものです。これに引っかかっったため、if文でエラー発生時の分岐の処理がされました。
注意点
参考にしたyoutubeの動画ではschema.validateではなく
Joi.validate(req.body,schema)
を使用していましたが、このメンバ関数は最新版(2022.9.現在)のnode.jsでは廃止されていて使えません。
配列の条件判定
入力が配列の場合です。面倒なので、サンプルの入力をapp.js内できめてしまいました。だから、node appを実行するだけで結果がターミナルに出力されます。
const express = require('express');
const path = require('path');
const Joi = require('joi');
const arrayString = ['banana','bacon','cheese'];
const userInput = { personalInfo: {
streetAdress: '123456789',
city: 'abrakatabra',
state: 'fl'
},
preferences : arrayString
};
const personalInfoSchema = Joi.object().keys({
streetAdress : Joi.string().trim().required(),
city : Joi.string().trim().required(),
state : Joi.string().trim().length(2).required()
});
const preferencesSchema = Joi.array().items(Joi.string());
const schema = Joi.object().keys({
personalInfo : personalInfoSchema,
preferences : preferencesSchema
});
objectの条件判定
const Joi = require('joi');
const arrayObject = [{example : 'example1'},{example : 'example2'},{example : 'example3'}];
const userInput = { personalInfo: {
streetAdress: '123456789',
city: 'abrakatabra',
state: 'fl'
},
preferences : arrayObject
};
const personalInfoSchema = Joi.object().keys({
streetAdress : Joi.string().trim().required(),
city : Joi.string().trim().required(),
state : Joi.string().trim().length(2).required()
});
const preferencesSchema = Joi.array().items(Joi.object().keys({
example : Joi.string().required()
}));
const schema = Joi.object().keys({
personalInfo : personalInfoSchema,
preferences : preferencesSchema
});
const validation = schema.validate(userInput);
if(validation.error){
console.log(validation.error);
}
else{
console.log(arrayObject);
}
ルーティング
別のjavascriptコードに飛ぶ方法です。ここでは/peopleに飛びたいと思います。このurlで実行するpeople.jsをroutesというフォルダに入れておきます。
//npm init --yes
//npm install express
const express = require('express');
const path = require('path')
const app = express();
app.use('/public',express.static(path.join(__dirname,'static')));
const people = require('./routes/people');
app.use('/people',people);
app.listen(3000);
const express = require('express');
const route = express.Router();
route.get('/',(req,res)=>{
res.send('/ bein hit');
});
route.get('/example',(req,res)=>{
res.send('/example bein hit');
});
module.exports = route;
app.jsを実行して、ブラウザで
localhost:3000/people
に飛ぶと、次のように出力され、
localhost:3000/people/example
に飛ぶと、
が出力されるので、ちゃんとpeople.jsが起動しています。