3
3

More than 1 year has passed since last update.

Node.jsの基礎(データの送受信)

Last updated at Posted at 2022-09-06

の続きです。

http通信

app.js
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

と検索すると、ブラウザに次の画面が表示されます。

image.png

なお、app.jsはずっと実行しっぱなしになっていると思うので、終わったらctrl+cで中断しておきます(以下の操作でも同様)。

htmlファイルの表示

app.jsと同じディレクトリにstaticというフォルダを用意して、次のhtmlファイルを入れます:

static/index.html
Test HTML file 

実行するJavascriptファイルは次のものです:

app.js
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を更新すると、ブラウザに

image.png

と表示されます。

フレームワークexpressの利用

コマンドプロンプトで

npm init --yes
npm install express

と打ち込んで、フレームワークの1つであるexpressパッケージをインストールします。以下、このフレームワークを使います。

Javascriptファイルに

app.js
const express = require('express');

と書けば、このobjectにexpressの中身が入っています。

get通信(urlから変数を読み込む)

app.js
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

と検索すると、

image.png

localhost:3000/example

と検索すると

image.png

とブラウザに表示されます。

また、

localhost:3000/pedro/99

では、

image.png

となり、ターミナルには

{ 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を使います。

app.js
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の書き方については触れません。

index.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

app.js
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を見ると以下のようなフォームが表示されます。

image.png

適当にメアドの欄にはaaa@gmail.com、パスワードの欄にはbbbbbbbbと打ちました。
次にsubmitボタンをクリックすると

image.png

と画面が切り替わり、以下のようにちゃんと入力した内容がreq.bodyとして読み込まれてターミナルに出力されています。

[Object: null prototype] {
  email: 'aaa@gmail.com',
  pasword: 'bbbbbbbb'
}

読み込んだ内容の条件判定

パッケージのインストール

npm install joi

API

index.htmlは先ほどのpost通信のものを使い、postで読み込んだデータが設定した条件を満たすか判定します。

app.js
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ボタンを押すと

image.png

がブラウザに表示され、ターミナルでも

[Object: null prototype] {
  email: 'aaa@gmail.com',
  password: 'bbbbbbbb'
}

となっています。

一方、

メアド:aaa@gmail.com
パスワード:c

としてsubmitボタンを押すと

image.png

がブラウザに表示され、ターミナルでは

[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ではなく

wrong.js
Joi.validate(req.body,schema)

を使用していましたが、このメンバ関数は最新版(2022.9.現在)のnode.jsでは廃止されていて使えません。

配列の条件判定

入力が配列の場合です。面倒なので、サンプルの入力をapp.js内できめてしまいました。だから、node appを実行するだけで結果がターミナルに出力されます。

app.js
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の条件判定

app2.js
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というフォルダに入れておきます。

app.js
//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);
routes/people.js
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

に飛ぶと、次のように出力され、

image.png

localhost:3000/people/example

に飛ぶと、

image.png

が出力されるので、ちゃんとpeople.jsが起動しています。

参考記事

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3