在WebSQL中存储包含二进制数据的JS字符串

时间:2014-06-20 08:10:22

标签: javascript string binaryfiles web-sql

我需要使用WebSQL存储包含二进制数据的JavaScript字符串。我知道可以使用用户技术(IndexedDB,LocalStorage,...),但由于某些原因,我需要坚持使用WebSQL。由于配额有限且数据可能变大,我不想对数据进行Base64编码。

考虑以下JS代码(和相应的JSFiddle):

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
function test(str){
    db.transaction(function (tx) {  
        tx.executeSql('DROP TABLE IF EXISTS test');
        tx.executeSql('CREATE TABLE test (val)');
        tx.executeSql('INSERT INTO test(val) VALUES (?)',[str]);
        tx.executeSql('SELECT val FROM test',[],function(tx,result){
            var str2 = result.rows.item(0).val;
            console.log(str + " (" + str.length + ") - " + str2 + " (" + str2.length + ")");
        });
    });
}
test("Foo");
test("A\0B");

输出

  

Foo(3) - Foo(3)

     

AB(3) - A(1)

在Chrome和Safari中。

正如你可以看到它被WebSQL吃掉之后的零字节和所有字符串。你知道是否有办法将这个字符串放入WebSQL而不扩大它(例如通过Base64编码),而不使用其他存储技术?

2 个答案:

答案 0 :(得分:0)

在websql中保存二进制数据的唯一方法是base64编码。 如果您的数据确实非常大并且倾向于超过5 / 10MB的浏览器配额限制,那么base64转换不会成为主要的罪魁祸首(它只会使数据膨胀平均因子为4/3)。 如果您的原始数据已经要越过配额,您最好考虑可能的解决方法。

答案 1 :(得分:0)

实际上确实有效。问题不是存储二进制字符串,而是检索它。当结果包含零字节时,字符串被认为已完成。

WebSQL提供函数hex,它返回String的十六进制表示。存储例如"A\0B"时,该函数将返回 410042 。使用这个我得到了我的榜样(见updated JSFiddle):

//convert hex representation back to string
function hex2str(hex){
    var result = new Array(hex.length / 2);
    for(var i = 0, j = 0; j < hex.length; i++, j+=2)
        result[i] = String.fromCharCode(parseInt(hex.substr(j,2),16));
    return result.join("");

}
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
function test(str){
    db.transaction(function (tx) {  
        tx.executeSql('DROP TABLE IF EXISTS test');
        tx.executeSql('CREATE TABLE test (val)');
        tx.executeSql('INSERT INTO test(val) VALUES (?)',[str]);
        //magic occurs here
        tx.executeSql('SELECT hex(val) as val FROM test',[],function(tx,result){
            var str2 = hex2str(result.rows.item(0).val);
            console.log(str + " (" + str.length + ") - " + str2 + " (" + str2.length + ")");
        });
    });
}
test("Foo");  //Foo (3) - Foo (3)
test("A\0B"); //AB  (3) - AB  (3)