【学習メモ】JavaScriptコードレシピ集 その13
JavaScriptコードレシピ集 の学習メモ 続きです。
- 作者: 池田泰延,鹿野壮
- 出版社/メーカー: 技術評論社
- 発売日: 2019/01/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Chapter14 さまざまなデータの送受信方法
229 JSONをパースしたい
文字列をJSONとして解析し、JavaScriptの値やオブジェクトに変換するには
JSON.parse()
メソッドを使います。
// JSON文字列 const item229_jsonString = `{ "students": 40, "grade": 4, "name": "C組" }`; // 文字列をJavaScriptのオブジェクトに変換 const item229_data = JSON.parse(item229_jsonString); console.log(item229_data); // 結果: {students: 40, grade: 4, name: "C組"} console.log(item229_data.students); // 結果: 40 console.log(item229_data.grade); // 結果: 4 console.log(item229_data.name); // 結果: "C組"
230 オブジェクトをJSONに変換したい
JSON.stringify()
メソッドを使うと、JavaScriptのオブジェクトをJSON文字列に変換できます。
const item230_data = { a: 1000, b: 'こんにちは、世界' }; const item230_str = JSON.stringify(item230_data); console.log(item230_str); // 結果: {"a":1000,"b":"こんにちは、世界"}
231 JSONの変換時にインデントを付けたい
JSON.stringify()
メソッドの第三引数はJSON文字列に改行とインデントを挿入するために使います。インデントとして利用したい文字列を指定します。数値を指定した場合はスペースの数になります。
数値を指定した場合はスペースの数とか、隠し機能っぽいですね
const item231_data = { a: 1000, b: 'こんにちは、世界' }; const item231_str = JSON.stringify(item231_data, null, ' '); console.log(item231_str); /* 結果: { "a": 1000, "b": "こんにちは、世界" } */
234 fetch()
メソッドでJSONを読み込みたい
ローカルサーバーなりでやる
await
・async
はPromise
による非同期処理を同期処理のようにわかりやすく書けることが利点です。
// await・async を使って記載した場合 async function load() { // ファイルを読み込む const item234_data = await fetch('assets/js/sample.json'); // JSONとして解析 const item234_obj = await item234_data.json(); // console.log(item234_obj); // 結果: {name: "別所分校", classes: Array(2)} // テキストを出力 const item234_str = JSON.stringify(item234_obj, null, ' '); console.log(item234_str); /* 結果: { "name": "別所分校", "classes": [ { "students": 40, "grade": 4, "name": "C組" }, { "students": 20, "grade": 2, "name": "B組" } ] } */ } load();
ここではJSONのみにしましたが、
- テキスト
- XML
- バイナリ(画像や3Dデータ)
も fetch()
で扱える。
237 fetch()
メソッドでデータを送信したい
ウェブサーバーのプログラムにデータを渡したいときにも
fetch()
メソッドを利用できます。データ送信方法として、GET
方式とPOST
方式の2種類があります。
方式 | 概要 | 特徴 |
---|---|---|
GET 方式 |
URLにパラメータを付与する方式 | URLでウェブページの結果が一意に決まるような場面で最適 SEOと相性が良い |
POST 方式 |
URLにフォームの送信情報が載らない | HTTPSプロトコルで通信している限りは POST の中身は第三者が見れない |
POST
で送信する場合はメソッドとヘッダー、ボディー情報を指定します。
JSONフォーマットで送る場合(application/json
方式)
JSONフォーマットでサーバーにデータを送る方法です。fetch()
メソッドの第二引数にオプションを指定します。
// JSONフォーマットで送る場合(`application/json` 方式) const item237_obj01 = { hello: 'world' }; const item237_data01 = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(item237_obj01) }; fetch('./new01', item237_data01) .then((res) => res.text()) .then(console.log);
<?php $json_string = file_get_contents('php://input'); ## 今回のキモ // PHPで文字列をJSOnデータとして展開する $obj = json_decode($json_string); echo $obj->{"hello"};
フォーム方式で送る場合(multipart/form-data
方式)
この方法はPHP側で値を受け取りやすいといったメリットがあります。
主に画像やテンプレファイルなどをサーバーにアップロードするときに multipart/form-data
方式が使われることが多い。
// フォーム方式で送る場合(`multipart/form-data方式`) const item237_body02 = new FormData(); item237_body02.set('hello', 'world'); const item237_data02 = { method: 'POST', body: item237_body02 }; fetch('./new02', item237_data02) .then((res) => res.text()) .then(console.log);
<?php echo $_POST["hello"];
238 XMLHttpRequestでテキストを読み込みたい
239 XMLHttpRequestでデータの読み込み状況を取得したい
fetch()
メソッドよりも昔から存在する機能でXMLHttpRequest
というJavaScriptの機能があります。XMLHttpRequest
はfetch()
メソッドよりも冗長な制御をしなければなりませんんが、低レベルの制御ができたり、古いブラウザーでも利用できたりするといった利点があります。
// XHR を作成 const item238_req = new XMLHttpRequest(); // 読み込み完了時のイベント item238_req.addEventListener('load', (event) => { // レスポンスを受け取る const item238_text = event.target.responseText; // テキストを出力 console.log(item238_text); }); // ファイルを指定 item238_req.open('GET', './assets/js/sample.txt'); // 読み込み開始 item238_req.send();
progress
イベントのイベントハンドラーでtotal
プロパティー(総容量)、loaded
プロパティー(現在の読み込み量)を取得すると何%のデータが読み込まれたかを取得できる。
item238_req.addEventListener('progress', (event) => { // 読み込みの割合を算出 const item238_rate = event.loaded / event.total; console.log(`${item238_rate * 100}%`); });
241 バックグランドでスクリプトを実行させたい
JavaScript はメインスレッドで動作しますが、負荷の高い処理を実行すると、その最中は操作不可能となります。JavaScript の処理がUIを担当するメインスレッドを止めてしまうためです。解決する手段のひとつに Web Worker という仕様があります。Web Worker はメインスレッドの JavaScript と分離して処理が実行されます。
注意点として、Web Worker はDOM操作ができない。
<div class="item241_wrap"> <input type="number" value="1" id="item241_numA"> + <input type="number" value="2" id="item241_numB"> = <span class="item241_result"></span> </div> <button class="item241_btn">計算する</button>
メインスレッドのJS
// 参照を取得 const item241_numA = document.querySelector('#item241_numA'); const item241_numB = document.querySelector('#item241_numB'); const item241_result = document.querySelector('.item241_result'); const item241_btn = document.querySelector('.item241_btn'); // ワーカーを作成 const worker = new Worker('./assets/js/worker.js'); // ボタンをクリックしたとき item241_btn.addEventListener('click', () => { worker.postMessage([Number(item241_numA.value), Number(item241_numB.value)]); console.log('[メインスクリプト] ワーカーへメッセージを送信'); }); // ワーカーから受信したとき worker.onmessage = function (e) { // 結果を画面に反映 item241_result.textContent = e.data; console.log('[メインスクリプト] ワーカーからメッセージを受信'); };
worker.js
onmessage = (e) => { console.log('[ワーカー] メインスクリプトからメッセージを受信'); // 足し算を実行 const item241_result = e.data[0] + e.data[1]; console.log('[ワーカー] メインスクリプトにメッセージを送信'); postMessage(item241_result); }
242 バックグランドでサービスワーカーを実行させたい
サービスワーカーは開いているWeb Pageの裏側で常に起動するスクリプトです。Web Worker はページが開いているときのみ実行されるのに対して、サービスワーカーはブラウザーを閉じていても実行できるという利点があります。
※ Safari12 はブラウザ終了には Service Worker は動作しない。
if ('serviceWorker' in navigator) { navigator.serviceWorker .register('./assets/js/sw.js') .then((registration) => { // 登録成功 console.log('ServiceWorkerの登録に成功', registration.scope); }) .catch((error) => { // 登録失敗 console.log('ServiceWorkerの登録に失敗', error); }); }
sw.js
self.addEventListener('fetch', (event) => { console.log('通信が発生', event.request); });
キャッシュ機能を利用するには Google が提供するライブラリ Workbox を利用するのがいいでしょう。