3

file://URI経由で使用できる Web アプリケーションを作成しようとしています。これは、AJAX を使用してバイナリ ファイルを読み込むことができないことを意味します (ブラウザのセキュリティ機能をオフにする必要はありません。これは原則として行いたくありません)。

アプリケーションは SQLite データベースを使用します。データベースをフォーマットで必要とするsql.jsコンストラクターに提供したいと考えていUint8Arrayます。

AJAX を使用してデータベース ファイルをロードすることはできないため、代わりに<input type="file">andFileReader.prototype.readAsArrayBufferを使用してロードしArrayBuffer、 をUint8Array. そして、それは次のコードで動作しています:

input.addEventListener('change', function (changeEvent) {
  var file = changeEvent.currentTarget.files[0];
  var reader = new FileReader();
  reader.addEventListener('load', function (loadEvent) {
    var buffer = loadEvent.target.result;
    var uint8Array = new Uint8Array(buffer);
    var db = new sql.Database(uint8Array);
  });
  reader.readAsArrayBuffer(file);
});

ただし、<input type="file">面倒なユーザーの操作が必要です。

ビルド ツールを使用してデータベース ファイルを JavaScript オブジェクト/文字列に変換し、ファイルの内容を提供する「.js」ファイルを生成してから、ファイルの内容を、Uint8Arrayどういうわけか。

疑似コード:

// In Node.js:
var fs = require('fs');
var sqliteDb = fs.readFileSync('path/to/sqlite.db');
var string = convertBufferToJsStringSomehow(sqliteDb);
fs.writeFileSync('build/db.js', 'var dbString = "' + string + '";');
// In the browser (assume "build/db.js" has been loaded via a <script> tag):
var uint8Array = convertStringToUint8ArraySomehow(dbString);
var db = new sql.Database(uint8Array);

Node.js では、次のことを試しました。

var TextEncoder = require('text-encoding').TextEncoder;
var TextDecoder = require('text-encoding').TextEncoder;
var sql = require('sql.js');

var string = new TextDecoder('utf-8').decode(fs.readFileSync('path/to/sqlite.db'));
// At this point, I would write `string` to a ".js" file, but for
// the sake of determining if converting back to a Uint8Array
// would work, I'll continue in Node.js...
var uint8array = new TextEncoder().encode(string);
var db = new sql.Database(uint8array);
db.exec('SELECT * FROM tablename');

しかし、それを行うと、「エラー: データベース ディスク イメージの形式が正しくありません」というエラーが表示されます。

私は何を間違っていますか?これは可能ですか?経由で同じファイルをロードしても、データベース ディスク イメージは「不正な形式」ではありませんFileReader

4

2 に答える 2

3

次のコードを使用して、データベース ファイルの内容をブラウザーに転送することができました。

// In Node.js:
var fs = require('fs');
var base64 = fs.readFileSync('path/to/sqlite.db', 'base64');
fs.writeFileSync('build/db.js', 'var dbString = "' + base64 + '";');
// In the browser (assume "build/db.js" has been loaded via a <script> tag):
function base64ToUint8Array (string) {
  var raw = atob(string);
  var rawLength = raw.length;
  var array = new Uint8Array(new ArrayBuffer(rawLength));
  for (var i = 0; i < rawLength; i += 1) {
    array[i] = raw.charCodeAt(i);
  }
  return array;
}
var db = new sql.Database(base64ToUint8Array(dbString));
console.log(db.exec('SELECT * FROM tablename'));
于 2016-09-27T04:54:06.753 に答える
1

そして、それは次のコードで動作しています:

input.addEventListener('change', function (changeEvent) {
  var file = changeEvent.currentTarget.files[0];
  var reader = new FileReader();
  reader.addEventListener('load', function (loadEvent) {
    var buffer = loadEvent.target.result;
    var uint8Array = new Uint8Array(buffer);
    var db = new sql.Database(uint8Array);
  });
  reader.readAsArrayBuffer(file);
});

ただし、<input type="file">面倒なユーザーの操作が必要です。

現在の作業アプローチを使用することは、回避策を作成するよりも面倒ではありません。ユーザーがアプリケーションを使用する場合、ユーザーはファイルシステムからファイルを選択してアプリケーションを実行できます。

于 2016-09-26T21:08:14.393 に答える