JavaScriptを使ったシンプルなSPAの作成例

SPA(Single Page Application)は、Webアプリケーションの一種で、ひとつのHTMLページ内でアプリケーションの状態遷移を行い、必要なデータだけを動的に取得することで、ユーザーがページを再読み込みすることなくアプリケーションを操作できるようにするものです。リクエストごとにHTMLを生成する従来のWebアプリケーションとは異なり、SPAではJavaScriptフレームワークやライブラリを使用し、フロントエンド側でHTML、CSS、JavaScriptを使ってページを構築し、サーバーサイドではAPIを提供することが一般的です。SPAはユーザーの体験を向上させるために、より柔軟でスムーズなユーザーインターフェイスを提供します。

本記事では、クライアント側でJavaScriptを使った、SPAの実装例を紹介します。
なお、本記事のサーバ側はNode.js+Expressで作成しています。

基本的な実装方法

サーバ側

サーバ側ではクライアントからの要求で更新するデータを送付するルーティング(API)を記載します。

app.post('/post-test', (request, response) => {
  const { sendData } = request.body;
  const result = sendData + " to server."
  response.send({ result: result });
});

クライアント側

JavaScriptのFetch APIを使います。

const data = {
  sendData: 'client'
};

fetch('/post-test', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data),
}).then((response) => {
  if (!response.ok) {
    throw('server error');
    return;
  }
  return response.json();
}).then((data) => {
  // data = response.json()の結果.
  if (data.result) {
    console.log(data.result); // client to server.
    return;
  }
}).catch((error) => {
  console.error(error);
});

上記は文字列の送信だけですが、リストのデータなどをサーバから送信することでページの表示を切り替えることが可能です。

参考:jQueryを使った記述方法

$.post('/post-test', { sendData: 'client' })
.done((data) => {
  if (data.result) {
    console.log(data.result); // client to server.
    return;
  }
});

各種データ送受信

素のJavaScriptを使って、各種データを送信・受信する方法を紹介します。

サーバ側、基本部分のソースコード
"use strict";

const express = require('express');
const fs = require('fs');
const path = require('path');

const app = express();
app.use(express.urlencoded({ limit: '5mb', extended: true, }));
app.use(express.json({ limit: '10mb', }));
app.use(express.static(path.join(__dirname, 'public')));

let httpServer = app.listen(8080, () => {
    console.log('http server start');
});

// ここにルーティングメソッドを書く.

バイナリデータの送信

サーバ側ルーティングメソッド

app.get('/get/get-image', (request, response) => {
    const filepath = path.join(__dirname, 'images', 'sample.jpg');
    const data = fs.readFileSync(filepath);
    response.send(data);
});

クライアント

response.blob()メソッドでレスポンスからバイナリデータを取得します。

function onDownloadImage() {
  fetch('/get/get-image')
  .then((response) => {
    if (!response.ok) {
      throw('Server error.');
    }
    return response.blob();
  }).then((blobData) => {
    // ダウンロードしたBlobをファイルに変換
    let link = document.createElement('a');
    link.href = window.URL.createObjectURL(blobData);
    link.download = 'download.jpg'; // 保存ファイル名.

    // ファイルをダウンロードするためにクリックイベントを発生させる
    a.click();

    // 使わなくなったリンク要素を削除
    window.URL.revokeObjectURL(link.href);
  }).catch((error) => {
    alert(error.\n${error});
  });
}

GETメソッドにクエリパラメータを送る

サーバ側ルーティングメソッド

app.get('/get/send-params', (request, response) => {
    console.log(request.query);
    response.sendStatus(200);
});

クライアント

URLSearchParamsを使うことで、アドレスに直接クエリパラメータを記述しなくても、簡単にパラメータを設定できます。

function onSendQuery() {
  const queryParams = new URLSearchParams({
    left: 0, right: 100, top: 0, bottom: 200
  });
  fetch('/get/send-params?' + queryParams)
  .then((response) => {
    if (!response.ok) {
      throw('Server error.');
    }
    confirm(response.status);
  }).catch((error) => {
    alert(error.\n${error});
  });
}
実行時、サーバ側のログ
{ left: '0', right: '100', top: '0', bottom: '200' }

オブジェクト(JSON)の送信

サーバ側ルーティングメソッド

app.post('/post/get-object', (request, response) => {
    let data = {};
    data['msg'] = 'response message.';
    data.type = 1;
    data.sub = { code: 2, display: 'TWO' };
    response.send(data);
});

クライアント

response.json()メソッドでレスポンスからJSON形式でオブジェクトを取得します。

function onGetObject() {
  fetch('/post/get-object', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ }) // パラメータなし.
  }).then((response) => {
    if (!response.ok) {
      throw('Server error.');
    }
    return response.json();
  }).then((data) => {
    console.log(JSON.stringify(data));
  }).catch((error) => {
    alert(error.\n${error});
  });
}
クライアント側のログ
{"msg":"response message.","type":1,"sub":{"code":2,"display":"TWO"}}
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です