我需要使用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编码),而不使用其他存储技术?
答案 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)