【问题标题】:Are there any characters that are not allowed in localStorage?localStorage 中是否存在不允许使用的字符?
【发布时间】:2013-11-03 06:18:31
【问题描述】:

我一直在使用localStorage以字符串格式存储一些二进制数据,虽然该值是肯定设置的(设置后立即alerting它,甚至设置后一段时间显示正确的值)它丢失了下次加载页面时。

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

我在设置二进制数据后立即添加了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,''); 进行了测试,并且成功保存了它。所以,我想知道规范在哪里说不能在字符串中使用控制字符。

【问题讨论】:

    标签: html local-storage binary-data


    【解决方案1】:

    我设置了test case,并在各种浏览器中运行了测试。结果如下(提到了字符代码的包含范围)。测试从支持localStorage的最低浏览器版本开始。

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

    所以,0x20 - 0xD7FF0xE000 - 0xFFFD 加上 0x090x0A0x0D 的字符范围是安全的。


    我创建了三个测试用例:

    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;}
    }
    

    【讨论】:

      【解决方案2】:

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

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

      因此,除了 HT、CR、LF 和 NUL 之外,没有任何空间是允许的。

      话虽如此,但仍然不知道为什么。

      【讨论】:

      • 是针对多个浏览器进行测试,还是只针对一个?
      • 您可能只在 IE 中测试过,因为我也在其他浏览器中创建并测试了该功能,结果显示不同(请参阅其他答案)。
      • Javascript 使用 UTF-16。您的正则表达式仅限于 ASCII。
      猜你喜欢
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 2012-02-28
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      相关资源
      最近更新 更多