[2021/06/02] JavaScript IndexedDB の使い方3(データ取得) (No.269)
[2021/06/01] JavaScript IndexedDB の使い方2(データ追加) (No.268)
[2021/05/31] JavaScript IndexedDB の使い方1(データベースオープン) (No.267)
[2021/05/27] JavaScript jQueryでAjaxを使いPHPからの画像データをcanvasに表示する方法 (No.266)
[2020/08/20] JavaScript jQueryでQRコードを表示する方法 (No.227)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
今回は「オブジェクトストア」に登録されたデータを取得する方法について説明します。
データを取得する場合でも、データ追加処理と同様にデータベースの「トランザクション」を取得し、 「トランザクション」から「オブジェクトストア」オブジェクトを取得します。
その後で「オブジェクトストア」オブジェクトの get メソッドでデータ取得のリクエストを行います。
get メソッドの書式とイベント関数の定義は以下の様になります。// getメソッド(objectStore:「オブジェクトストア」オブジェクト) var request = objectStore.get(id); request.onsuccess = function(event) { // 取得が成功した場合の関数宣言(event.target.result にデータが返る) }; request.onerror = function(event) { // 取得エラーの場合の関数宣言 }; <パラメータ> ・id:キー文字列またはキーの範囲指定 <戻り値> request :IDBRequest オブジェクト
get メソッドが成功した時には event.target.result にデータが返るので、ここで行いたい処理を記述します。
以下に簡単な get メソッドの利用ソースを示します。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - add - 2</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // ブラウザ対応宣言 window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; // データベース(IDBDatabase)インスタンス var db; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ取得処理 */ function getData() { //キー値 var id = $("#id").val(); //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //一件取得 var request = objectStore.get(id); //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; console.log('データ:', result); }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - add - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> id:<input type="text" name="id" id="id" value="" /> <button id="buttonGet" onclick="getData()">データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 ID のテキストボックスに「01」を入力し「データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールにデータが表示されるのが分かります(下図参照)。
そこで ID のテキストボックスをクリアし「データ取得」ボタンをクリックすると、コンソールに undefined と表示されます。 また「111」などのキーが存在しないで「データ取得」ボタンをクリックしても同様に undefined と表示されます。
データが undefined の判定処理を onsuccess イベントに追加して undefined では無い場合にデータ処理を行う様に変更します。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - get - 2</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // ブラウザ対応宣言 window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; // データベース(IDBDatabase)インスタンス var db; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ取得処理 */ function getData() { //キー値 var id = $("#id").val(); //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //一件取得 var request = objectStore.get(id); //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; if (result !== undefined) { console.log('データ:', result); } else { console.log('データが見つからない!!'); } }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - get - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> id:<input type="text" name="id" id="id" value="" /> <button id="buttonGet" onclick="getData()">データ取得</button> <br /> </body> </html>
関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
PR -
前回は IndexedDB の「データベース」および「オブジェクトストア」の作成を説明しましたが、 データベースの入れ物ができれば次に行うのはデータの登録ではないでしょうか。
今回は「オブジェクトストア」にデータを追加する方法について説明します。
データベースに対してデータの追加を行う場合には「トランザクション」と言うものを使用します。
この「トランザクション」ですがデータベースの「オブジェクトストア」に対して何かの処理を行う時には、開始しなければならない様です。
トランザクションは readonly、readwrite、versionchange の3個のモードがありますが、 versionchange はデータベースのオブジェクトストアやインデックスを作成または削除する場合に使いますが、 今回はデータの操作なので readwrite を指定します。 なお readonly はデータの取得(参照)のみの場合に利用します。
トランザクション開始の書式とイベント関数の定義は以下の様になります。
// トランザクション開始(IDBDatabase.transaction()) var transaction = db.transaction(storeNames, [ mode , [ options ] ] ); // (db : データベースオープンの成功時に退避されたデータベースインスタンス) <パラメータ> ・storeNames:オブジェクトストア名を文字列配列、または文字列(単一の場合)で指定します。 ['store1', 'store2', 'store3', ...] の様に配列か 'store1' の1個の指定でもOK var transaction = db.transaction(db.objectStoreNames); ⇒ データベースの全てのオブジェクトストア指定 ・mode :"readonly", "readwrite", "versionchange" ・options :"default", "strict", "relaxed" (通常は指定無しでOKです) <戻り値> transaction :IDBTransaction オブジェクト このオブジェクトの正常時とエラー時イベントハンドラにユーザ関数を定義して各処理を行う。 // イベントの関数定義 transaction.oncomplete = function(event) { // トランザクションが正常に終了した場合に呼ばれる関数宣言 }; transaction.onerror = function(event){ // トランザクションでエラーが発生した場合に呼ばれる関数宣言 };
このトランザクションから「オブジェクトストア」オブジェクトを取得し、データ処理を行います。// トランザクション開始(IDBDatabase.transaction()) var transaction = db.transaction(storeNames, [ mode , [ options ] ] ); // 「オブジェクトストア」オブジェクトを取得 var objectStore = transaction.objectStore(storeName); <パラメータ> ・storeName:オブジェクトストア名を文字列で指定します。 <戻り値> objectStore :IDBObjectStore オブジェクト
■IDBObjectStoreのメソッドメソッド 処理 説明 add データ追加 新規のデータをオブジェクトストアに追加する。
戻り値 IDBRequest の onsuccess , oneerror イベントで処理が必要であれば宣言する。clear 全データ削除 オブジェクトストアの全データを削除する。
戻り値 IDBRequest の onsuccess , oneerror イベントで処理が必要であれば宣言する。count データ件数取得 件数検索にキーまたは、キーの範囲指定により件数取得する。
キー(範囲)の指定が無ければ、オブジェクトストアの全件数を取得する。
戻り値 IDBRequest の onsuccess イベントで件数取得する。delete データ指定削除 キーまたは、キーの範囲指定によりデータ削除する。
戻り値 IDBRequest の onsuccess , oneerror イベントで処理が必要であれば宣言する。get データ取得 キーの指定によりデータ取得する。
戻り値 IDBRequest の onsuccess イベントでデータ取得する。getAll 指定全データ取得 件数検索にキーまたは、キーの範囲指定によりデータ取得する。
データ取得はカーソル処理を使って行う。openCursor カーソルオープン 件数検索にキーまたは、キーの範囲指定によりカーソルオープンする。
戻り値 IDBRequest の onsuccess イベントでカーソル(event.target.result)が返される。
カーソルの continue() メソッドで次のカーソルへ処理が移る。
IDBObjectStoreのメソッドは上記の他にもありますが、それは「MDN Web Doc」を参照して頂くとして、 このブログではこれらを順に説明していきます。
まず最初にデータの追加「add」メソッドについて説明します。
■データ追加処理
IDBObjectStore の add メソッドを使ったデータ追加の例を以下に示します。
データベースオープン処理は、前回の記事とほぼ同じですが、 データベース名、オブジェクトストア名は先頭の方で宣言する様にしています。
IDBObjectStore の add メソッドの引数にはデータのオブジェクトを渡しますが、 オブジェクトストアの生成で指定した keyPath の要素名は必須です。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - add - 1</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // ブラウザ対応宣言 window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; // データベース(IDBDatabase)インスタンス var db; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //DBが存在しない場合、またはバージョン引数よりも小さい場合の作成処理 request.onupgradeneeded = function(event) { //データベースインスタンス保存 db = event.target.result; db.onerror = function(event) { //エラー処理 console.log('DBの作成に失敗しました。'); }; //オブジェクトストア名の確認 if (!db.objectStoreNames.contains(objStoreName)) { //オブジェクトストアが無い場合 var objStoreKey = { keyPath: 'id' }; //キー設定 //var objStoreKey = { autoIncrement: true }; //autoIncrementのみ指定 //オブジェクトストア生成 var obj = db.createObjectStore(objStoreName, objStoreKey); console.log("オブジェクトストア生成"); } }; //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ追加処理 */ function addData() { //トランザクション var transaction = db.transaction(objStoreName, 'readwrite'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //オブジェクトストアに追加のリクエストします。 var data = { id: '01' , //キーデータ data1: 'abcde' , //文字列データ data2: 123 , //数値データ data3: { data3_1: '001', data3_2: 1000 } //オブジェクトデータ }; var request = objectStore.add(data); //追加正常の場合の関数宣言 request.onsuccess = function(event) { console.log('保存成功'); }; //追加エラーの場合の関数宣言 request.onerror = function(event) { console.log('保存失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - add - 1</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonAdd" onclick="addData()">データ追加</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後「データ追加」ボタンをクリックすると、 データベース「TestDB」の中にオブジェクトストア「Test1」が生成され、その中にデータが1件存在することが分かります。再度「データ追加」ボタンをクリックするとエラーが発生し、データが追加されません。
オブジェクトストアの生成で指定した keyPath の指定があるので id は重複キーを許可されません。
但し、オブジェクトストア生成の前でコメント行としている autoIncrementのみ指定 に変更すれば、 データ項目の中の主キーの指定が無くなります。
そこで、HTMLファイルを変更し再度ブラウザに読込みを行います。この後でブラウザの「ウエブ開発ツール」上でデータベースを削除を行います。
再度「DBオープン」ボタンをクリック後「データ追加」ボタンを複数回クリックすると、同じデータがオブジェクトストアに登録されます。
この場合、オブジェクトストアのなかでは「Key」という項目でデータが付加されその値が順次増加(autoIncrement)していきます。
そこで少しソースを変更し、複数のデータを登録できる様に変更します。 「addData」関数をサブ関数として与えられるデータが配列でも処理できる様にします。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - add - 2</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // ブラウザ対応宣言 window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; // データベース(IDBDatabase)インスタンス var db; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //DBが存在しない場合、またはバージョン引数よりも小さい場合の作成処理 request.onupgradeneeded = function(event) { //データベースインスタンス保存 db = event.target.result; db.onerror = function(event) { //エラー処理 console.log('DBの作成に失敗しました。'); }; //オブジェクトストア名の確認 if (!db.objectStoreNames.contains(objStoreName)) { //オブジェクトストアが無い場合 var objStoreKey = { keyPath: 'id' }; //キー設定 //オブジェクトストア生成 var obj = db.createObjectStore(objStoreName, objStoreKey); console.log("オブジェクトストア生成"); } }; //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ追加処理SUB */ function _addData(data) { //トランザクション var transaction = db.transaction(objStoreName, 'readwrite'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //単独データを1件の配列データにする var arrData = new Array(); if (Array.isArray(data) == false) { arrData[0] = data; } else { arrData = data; } for (var i in arrData) { //オブジェクトストアに追加のリクエストします。 var request = objectStore.add(arrData[i]); //追加正常の場合の関数宣言 request.onsuccess = function(event) { console.log('保存成功'); }; //追加エラーの場合の関数宣言 request.onerror = function(event) { console.log('保存失敗。event:', event); }; } } /** * データ追加処理 */ function addData() { //配列データの例 var data = [ { id: '01' , data1: 'abcde' , data2: 123 , data3: { data3_1: '001', data3_2: 1000 } }, { id: '02' , data1: 'a0002' , data2: 200 , data3: { data3_1: '002', data3_2: 2000 } }, { id: '03' , data1: 'a0003' , data2: 300 , data3: { data3_1: '003', data3_2: 3000 } }, { id: '11' , data1: '11111' , data2: 111 , data3: { data3_1: '101', data3_2: 1111 } }, { id: '22' , data1: '2222' }, { id: '33' , data2: 222 } ]; //単独データの例 //var data = { id: '11' , data1: '11111' , data2: 111 , data3: { data3_1: '101', data3_2: 1111 } }; _addData(data); } </script> </head> <body> <h2>test IndexedDB - add - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonAdd" onclick="addData()">データ追加</button> <br /> </body> </html>
このソースではオブジェクトストアの生成で keyPath の指定があるので id は重複キーを許可されませんので、 データの中の「id」はユニークになる様に設定します。
そこで、HTMLファイルを変更し 配列データを登録する様にして再度ブラウザに読込み、ブラウザの「ウエブ開発ツール」上でデータベース「TestDB」のオブジェクトストア「Test1」の全データの削除を行います。 その後「DBオープン」ボタンさらに「データ追加」ボタンをクリックします。
そうしますと、以下の図の様にオブジェクトストア「Test1」に6件のデータが登録されます。
ここで注意点ですが、データの「id」は必須なのですが、その他のデータは指定されたままの状態で登録されています。 登録されるデータの制約は keyPath で指定された要素名が存在すればよく、その他は Javascript のオブジェクトであればOKな様です。関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
-
今回はブラウザ内にで用意されているローカルなデータベース機能を提供する IndexedDB の使い方について説明します。
IndexedDB はローカルなブラウザに、キーインデックスを付加したひとかたまりのJavaScript オブジェクトを保存できます。
このデータベースはブラウザのプログラムを終了してもローカルなフォルダに保存されているので、 再度同じWEBページを開いた時にデータを再利用ができます。
尚、この IndexedDB は MySQL の様なリレーショナルデータベースとは全く異なり、以下の点で注意が必要です。- テーブルの概念は無く代わりに「オブジェクトストア」と呼ばれるものがあります。
- データ処理は SQL 文で処理せず「オブジェクトストア」用の追加、更新、削除、取得などのメソッド(API)を使用します。
- データ取得は「オブジェクトストア」のカーソルをオープンし順次処理します。
- IndexedDBのAPIは、ほぼ非同期処理で処理結果に対応する関数を渡します。(XMLHttpRequestの様な)
先ずは IndexedDB を使うにあたって以下のものを最初に宣言します。
以前は Google Chrome と Firefox ではベンダープレフィックスを付けた名称だったため、今回も取敢えず宣言します。
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
■IndexedDB オープンメソッド
通常のデータベースと同様に IndexedDB のデータベースを使用時には最初にオープン処理が必要です。
オープン処理は open 関数を使いますが書式は以下の通りです。 尚、オープン処理と同時に各種のイベント関数を宣言し、オープン処理結果を待ち受けてやります。// オープン処理 var request = indexedDB.open( dbName [ , verNo ] ); <パラメータ> ・dbName:データベース名を文字列で指定します。 ・verNo :バージョンNOを数値で指定します。 <戻り値> request :IDBOpenDBRequest オブジェクト このオブジェクトのイベントハンドラにユーザ関数を定義して各処理を行う。 // イベントの関数定義 request.onupgradeneeded = function(event) { // 初回オープン時または、バージョンNOが登録済みより大きい場合に呼ばれる関数宣言 }; request.onsuccess = function(event) { // 接続が正常に終了した場合に呼ばれる関数宣言 }; request.onerror = function(event){ // オープン時にエラーが発生した場合に呼ばれる関数宣言 };
■簡単な IndexedDB オープン処理
以下に IndexedDB のオープン処理の簡単な例を示します。
データベース名は「TestDB」としてオープンのリクエストを行い onsuccess , onerror イベントの処理を宣言しています。
onsuccess のイベントの中の request.result は IDBDatabase のインスタンスですので、グローバルな変数に保存します。 このインスタンスを使って各種のデータ処理が行える様になります。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - 1</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // ブラウザ対応宣言 window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; // データベース(IDBDatabase)インスタンス var db; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open("TestDB"); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; alert("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ alert("DBオープンエラー"); }; } </script> </head> <body> <h2>test IndexedDB - 1</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <br /> </body> </html>
下図はこのHTMLファイルを FireFox で呼出した直後で、「ツール」⇒「ブラウザツール」⇒「ウエブ開発ツール」を開いたところです。
「ストレージ」 の項目を見ると 「Indexed DB」 がありますので、 その中の 「http://localhost」 をさらにみるとまだ何も存在しないことが分かります。
ブラウザのサイトの「DBオープン」をクリックして再度 「ストレージ」 の項目の 「Indexed DB」 の 「http://localhost」 をみると 「TestDB」 が作成されていることが分かります。
(これを見る場合には一旦「ウエブ開発ツール」を閉じてから再度開く必要があります)
「TestDB」 は作成されましたが Indexed DB のテーブルの様な「オブジェクトストア」が存在しないので、これを作成してみます。
上記の HTML ファイルのソースに onupgradeneeded イベントを追加し、その中で「オブジェクトストア」を生成する様に変更します。 ファイルは以下の様になります。
■オブジェクトストアの生成を伴う IndexedDB オープン処理
<html> <head> <meta charset="utf-8"> <title>test IndexedDB - 1 - 2</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // ブラウザ対応宣言 window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; // データベース(IDBDatabase)インスタンス var db; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open("TestDB"); //DBが存在しない場合、またはバージョン引数よりも小さい場合の作成処理 request.onupgradeneeded = function(event) { //データベースインスタンス保存 var db = event.target.result; db.onerror = function(event) { //エラー処理 alert("DBの作成に失敗しました。"); }; var objStoreName = "Test1"; //オブジェクトストア名 if (!db.objectStoreNames.contains(objStoreName)) { //オブジェクトストアが無い場合 var objStoreKey = { keyPath: 'id' }; //キー設定 //オブジェクトストア生成 var obj = db.createObjectStore(objStoreName, objStoreKey); } }; //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; alert("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ alert("DBオープンエラー"); }; } </script> </head> <body> <h2>test IndexedDB - 1 - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <br /> </body> </html>
最初の処理で作成された 「TestDB」 を削除するために、「ツール」⇒「ブラウザツール」⇒「ウエブ開発ツール」を開きます。
「ストレージ」 の項目を見ると 「Indexed DB」 があるのでその中の 「http://localhost」 の 「TestDB」 で右クリックをして「"TestDB(Default)"を削除」メニューを実行します。
さらに、上記の「オブジェクトストア」の生成を含んだHTMLファイルを読み込み「DBオープン」をクリックして再度データベースの生成を行います。
「ストレージ」 の項目の 「Indexed DB」 の 「http://localhost」 をみると 「TestDB」 が作成され、 その中に 「Test1」 の「オブジェクトストア」が存在することが分かります。
(これを見る場合には一旦「ウエブ開発ツール」を閉じてから再度開く必要があります)
尚、ここでデータベース「IDBDatabase」の createObjectStore メソッドに付いて説明します。// 書式 var obj = IDBDatabase.createObjectStore(name [, options] ); <パラメータ> ・name :オブジェクトストア名を文字列で指定します。 ・options :オプションパラメーターとなる属性を持つオプションオブジェクト。 これは次のプロパティを持つ。 //optionsプロパティ ・keyPath :オブジェクトストアの主キー(in-line keys)として使用されるデータ内の項目名。 空や特定されていない場合 Key Path なしで生成されて out-of-line keys が使用される。 ・autoIncrement:trueだった場合、オブジェクトストアはkey generatorを持つ。既定値はfalse。 <戻り値> obj :IDBObjectStoreオブジェクト
キーパス (keyPath) と キージェネレータ(autoIncrement) の指定方法の違いによる説明は以下の通りです。
キーパス(keyPath) キージェネレータ(autoIncrement) 説明 指定なし 指定なし オブジェクトストアは、数値や文字列といったプリミティブ値を含む、どのような種類の値でも保持できます。
新たな値の追加を望むたびに、個別のキー引数を供給しなければなりません。指定あり 指定なし ブジェクトストアは、JavaScript オブジェクトのみ保持できます。
オブジェクトはキーパスと同じ名称のプロパティを持たなければなりません。指定なし 指定あり このオブジェクトストアは、どのような種類の値でも保持できます。
キーは自動的に生成されます。また、特定のキーを使用したい場合は個別のキー引数を供給できます。指定あり 指定あり このオブジェクトストアは、JavaScript オブジェクトのみ保持できます。
通常はキーが生成されて、オブジェクトでキーパスと同じ名称を持つプロパティに、生成されたキーの値を保存します。
ただしそのようなプロパティがすでに存在している場合は、生成された新たなキーではなく、そのプロパティの値をキーとして使用します。(MDN Web Doc より)
さて、ここまでで「データベース」と「ブジェクトストア」の生成が終わりましたので、 別の記事でデータ処理に付いて説明を行いたいと思います。
keyPath と autoIncrement の指定ですが keyPath を指定あり autoIncrement を指定なしの指定で今後は進めていきます。 (主キーを文字列データで与えてデータ登録を行う感じです。)
関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
-
canvas に FileReader オブジェクトを使って、ローカルなコンピューター内にある画像ファイルを読み込むことを説明しました。 今回はこの方法に倣って、作成済みの画像データ表示関数を使って PHP から JSON データで送信されてくる画像ファイルデータを描画する方法について説明します。
処理の手順は以下の通りです- ページロード時イベントで Ajax を使って PHP の画像ダウンロードプログラムの呼出
- Ajax の正常終了時に JSON データから Blob データ生成
- FileReader を生成,画像の描画
- FileReader の readAsDataURL メソッドで Blob データを引数としてコール
- FileReader の onload イベントで canvas への画像表示関数の実行
■Ajaxを使いPHPからの画像データをcanvasに表示
<html> <head> <meta charset="utf-8"> <title>test canvas</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> //Image関数 function drawImage(imageFile) { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //イメージオブジェクト var img1 = new Image(); //画像ファイル指定でファイル読込開始 img1.src = imageFile; //画像ロード後に画像を描画できる。 img1.onload = function(){ //画像の大きさを設定 width = img1.width; height = img1.height; canvas.attr('width' , width); canvas.attr('height', height); //画像を描画 ctx.drawImage(img1, 0, 0, width, height); } return false; } // Base64とMIMEタイプからBlobオブジェクト作成 function toBlob(base64, mimetype) { var bin = atob(base64.replace(/^.*,/, '')); var arr = new Uint8Array(bin.length); for (var i = 0; i < bin.length; i++) { arr[i] = bin.charCodeAt(i); } // Blobを作成 try{ var blob = new Blob([arr.buffer], { type: mimetype }); }catch (e){ return false; } return blob; } //ページロード時イベント $(function() { var file = null; // 選択されるファイル // データの取得 $.ajax({ type: "POST" , url: "./imagedown.php" , data: "" }).done(function(res){ // ajaxがOK var data = JSON.parse(res); // blobデータ生成 var blob = toBlob(data.img, data.type); //FileReader API var reader = new FileReader(); //ファイルロード終了時イベント宣言 reader.onload = function(e) { //画像表示関数コール drawImage(e.target.result); }; //Blobデータ読込の開始 reader.readAsDataURL(blob); }).fail(function(XMLHttpRequest, textStatus, error) { // 取得エラー alert(error); }).always(function() { // 後処理(処理することが在れば) }); }); </script> </head> <body> <h2>test canvas4</h2> <canvas id="canvas" width="100" height="100" style="border: 1px solid #000000;"></canvas> <br /> </body> </html>
■PHPの画像データダウンロード処理
PHP のプログラムの手順は以下の通りです- file_get_contents 関数でファイルを読込
- 読込データを base64_encode 関数でBASE64にエンコード
- エンコード済みBASE64データと画像タイプを Ajax 用のデータとして準備
- json_encode 関数で Ajax に送信
<?php // ファイル $file_name = './img1.jpg'; //仮に同一フォルダに「img1.jpg」の画像ファイルを置く $type = 'image/jpeg'; // base64エンコード $img = base64_encode(file_get_contents($file_name)); // Ajax応答データ $list = array("img" => $img, "type" => $type); // JSONデータを出力 echo json_encode($list); exit(); ?>
今回は HTML のページ読み込み時のタイミングで Ajax で画像を表示する処理を行いました。
手順としては回りくどい処理になっていますが、この方法を使えば別のタイミング、 例えばあるボタンやリンクをクリックした時に画像を変更する場合には使えるのではと思います。
単にページに画像を表示するだけならば IMG タグで画像を指定すればできます。
以下にBASE64にエンコードしたデータを直接表示する場合を示します。
■PHPで画像データをBASE64にエンコードしたデータを直接表示
<?php //ファイル $file_name = './img1.jpg'; $type = 'image/jpeg'; // base64エンコード $img = base64_encode(file_get_contents($file_name)); ?> <html> <head> <meta charset="utf-8"> <title>test image</title> </head> <body> <h2>test image</h2> <img width="100" src="data:<?php echo $type; ?>;base64,<?php echo $img; ?>" /> <img width="100" src="<?php echo $file_name; ?>" /> </body> </html>
関連する記事
⇒JavaScript jQueryでcanvasを使い図形を描画する方法
⇒JavaScript jQueryでcanvasを使い画像ファイルを表示する方法
⇒JavaScript jQueryでFileReaderを使いcanvasに画像ファイルを表示する方法
-
今回は QRコード を画面上に表示する方法について説明します。
QRコード と言えばトヨタ自動車系列の会社である株式会社デンソー(現在はデンソーウェーブ)が開発したマトリックス型の二次元コードです。 このコードの中にはASCII(半角英数)で最大4296文字まで入るため、各種の情報を埋め込むことができます。
デンソーは敢えて普及のため QRコード の特許をオープンし特許権を行使していないため、自由に使用できます。
最近は非常に普及が進み、現在はスマホのカメラアプリにも QRコード の読み取りが標準で装備されていて、いろんなシーンで利用されています。 テレビ画面にもスマホのためのURLが QRコード で表示され、このコードを見ない日が無いぐらいです。
さてこの QRコード をブラウザの画面上に表示する方法について話を戻します。
先ずはプログラムが必要無く HTML の IMG タグに直接指定する方法について説明します。
Google Chart Tools を使うのですが、チャートのタイプとして QRコード を指定し、コードの中身のテキスト文字列を指定するだけで QRコード の画像が表示されます。
■Google Chart Tools を使い QRコード を表示するHTMLファイル
<html> <head> <meta charset="utf-8"> <title>test qr code</title> </head> <body> <img src="https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=this is test"> </body> </html>
上記の QRコード の部分を実際に表示すると以下の様になります。
Google Chart Tools への URL は「https://chart.apis.google.com/chart?」でその後ろに生成する QRコード の情報を指定します。<パラメータの指定方法> cht=qr : QRコードを指定(必須) chs=<width>x<height>: QRコードのサイズを指定。width,height 共に同じ値(必須) chl=<data> : コードの中身のテキスト文字列(必須) choe=<encoding> : データをQRコードにエンコードする方法。 利用可能な値は次のとおりです。 ・UTF-8 [デフォルト] ・Shift_JIS ・ISO-8859-1 chld=<error_correction_level>|<margin> : error_correction_level : 誤り訂正レベル ・L-[デフォルト]最大7%の誤り訂正 ・M-最大15%の誤り訂正 ・Q-最大25%の誤り訂正 ・H-最大30%の誤り訂正 margin : QRコードの周りの白い幅でピクセル値では無い([デフォルト:4])
このAPIにより返される画像データ形式は「PNG」の様です。「PNG」が表示できないブラウザでは QRコード が表示されませんので注意して下さい。 (現状ではそんなブラウザは無いと思いますが)
なお、このAPIのGoogle の正式ページは以下の通りです。
⇒https://developers.google.com/chart/infographics/docs/qr_codes
このページの先頭には以下の注意書きがあります。Warning: This API is deprecated. Please use the actively maintained Google Charts API instead. See our deprecation policy for details.
「このAPIは非推奨になっています。 代わりにGoogle Charts APIを使用してください。 」とありますので、 いつ使えなくなっても仕方ありません。 現状では「Google Charts API」を見ても QRコード の項目は見当たらないので、代替の方法を考えなければと思います。
と言うことで、以下は QRコード用jQuery ライブラリを使った方法について説明します。
ここでは qrcode.js ライブラリを使用します。
■ qrcode.js ライブラリのダウンロード
qrcode.js ライブラリのダウンロードは以下のページから行えます。
⇒https://github.com/jeromeetienne/jquery-qrcode
ページ右上の「↓Code」ボタンをクリックしてさらに「Download ZIP」をクリックします。
ZIPファイルのダウンロードが始まりますので適当なフォルダを設定してダウンロードさせます。
ZIPファイルを解凍し「jquery.qrcode.min.js」をHTMLから参照できるところにコピーします。 (今回のテストではHTMLファイルと同じフォルダにしました。)
■ qrcode.js ライブラリの使用例
以下に qrcode.js ライブラリの使用例を示します。
HTMLファイルと同じディレクトリに「jquery.qrcode.min.js」を設置しヘッダーで読込みます。
qrcode.js が QRコード を画像展開する「DIVタグ」を宣言します。
javascript ではファイルロード直後に「DIVタグ」に対して QRコード を展開するコードを記述します。<html> <head> <meta charset="utf-8"> <title>test qrcode</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script src="./jquery.qrcode.min.js"></script> <script type="text/javascript"> $(function(){ $('#qrcode').qrcode({ render: "canvas", width : 150, height: 150, text: "this is test." }); }); </script> </head> <body> <div id="qrcode"></div> </body> </html>
<qrcode のパラメータオブジェクトの指定方法> render : 生成方法の指定「"canvas","table"のみ」(オプションでデフォルト:"canvas") width : QRコードのサイズ幅を指定。 height : QRコードのサイズ高さを指定。 text : コードの中身のテキスト文字列(必須)
上のソースの QRコード の部分をブラウザのウエブ開発などでのぞいてみると、 canvas 指定の場合には「DIVタグ」の中身に以下のHTMLが生成され、画像データが存在します。
<canvas width="150" height="150"></canvas>
また table 指定の場合には「DIVタグ」の中身に以下の様なHTMLが生成され、 「tdタグ」の背景色で黒白のドットを生成している様です。
<table style="width: 150px; height: 150px; border: 0px none; border-collapse: collapse; background-color: rgb(255, 255, 255);"> <tbody> <tr style="height: 6px;"> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> </tr> <tr style="height: 6px;"> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> <td style="width: 6px; background-color: rgb(255, 255, 255);"></td> <td style="width: 6px; background-color: rgb(0, 0, 0);"></td> ... 後は割愛