3

我一直在使用 localStorage 以字符串格式存储一些二进制数据,尽管该值已明确设置(alert设置后立即设置,甚至设置后一段时间显示正确的值),但当页面下次加载时它会丢失。

起初我认为这可能是因为数据包含空字节,所以我重新设计了压缩器,使其永远不会输出它们。但是,这没有任何区别,因为价值仍然丢失。

localStorage.testing = 1在设置二进制数据后立即添加。即使另一个值丢失,该值也会保留。

我绝对肯定没有代码delete localStorage.myitem

什么可能导致此问题?

如果有帮助,这是我要存储的数据,以十六进制表示:

0x1103c0a0   0xd6cf0305   0xc0a0d6cf   0x0307c0a0   0xd6cf0309   0xc0a0d6cf
0x030bc0a0   0xd6cf030d   0xc0a0d6cf   0x0311c0a0   0xd6cf0313   0xc0a0d6cf   0x0301

编辑:我刚刚测试localStorage.testvalue = realvalue.replace(/[\x00-\x1f]/g,'');并成功保存了它。所以,我想知道规范在哪里说不能在字符串中使用控制字符。

4

2 回答 2

13

我已经设置了一个测试用例,并在各种浏览器中运行了测试。结果如下(提到了字符代码的包含范围)。测试从支持localStorage.

  • 铬 5 - 20:0x0000-0xFFFF
  • 歌剧 10.50 - 12.00: 0x0000-0xFFFF
  • Safari 4.0 - 5.1.7:0x0000-0xFFFF
  • Firefox 3.5 - 16 alpha : 0x0000-0xD7FF0xE000- 0xFFFE(0xD800-0xDFFF 和 0xFFFF 在 LS 后变成两个字符)
  • IE8, IE9, IE10 PP6 : 0x0009, 0x000A, 0x000D, 0x0020-0xD7FF0xE000- 0xFFFD。(其他范围要么被忽略,要么导致“无效参数”错误)。
    0x0000是一个 NULL 字节,它会截断 IE 中的所有后续字符。

因此,字符范围0x20-0xD7FF0xE000- 0xFFFDplus 0x090x0A并且0x0D是安全的。


我创建了三个测试用例:

  1. 最快的测试用例,它创建一个包含所有字符的字符串,并测试设置后的值localStorage
  2. 一种使用空格字符 (0x20) 作为分隔符的方法,以正确处理创建长度为 2 的字符的浏览器。
  3. 最糟糕的方法,因为 IE 对无效字符串抛出错误。每个字符都是单独测试的,这是相当昂贵的。

JSFiddle中提供了所有测试功能,第一个测试用例如下所示:

function run_test(lowerlimit, UPPERLIMIT) {
    try {
        if (!window.localStorage) {
            // I recall that in one of the older Chrome version (4),
            // localStorage === null
            return 'Localstorage is not supported';
        }
        if (isNaN(lowerlimit) || isNaN(UPPERLIMIT) || lowerlimit > UPPERLIMIT) {
            return 'One of the limits is not a valid number!';
        }
        var i = lowerlimit - 1;
        var character_range = [];
        while (++i < UPPERLIMIT) character_range.push(i);
        input = String.fromCharCode.apply(String, character_range);
        localStorage.setItem('chartest', input);
        output = localStorage.getItem('chartest');
        if (input === output) {
            return true;
        }
        // Uh oh, not equal!
        var result = [];
        for (i=0; i<UPPERLIMIT-lowerlimit; i++) {
            if (input[i] !== output[i]) {
                result.push(i + lowerlimit);
            }
        }
        return result;
    }catch(e){return 'Error:' + e;}
}
于 2012-06-23T23:00:41.913 回答
0

经过进一步测试,似乎当 localStorage 说它存储字符串时,它的真正含义是它存储匹配的字符串:

/^[\x00\x09\x0A\x0D\x20-\xff]*$/

因此,除了 HT、CR、LF 和 NUL 之外,在空格之前没有任何内容。

也就是说,仍然不知道为什么。

于 2012-06-23T15:45:56.027 回答