【问题标题】:String.replace strange behaviour in IE11String.replace IE11 中的奇怪行为
【发布时间】:2015-11-23 18:53:31
【问题描述】:

我在 IE11 上遇到了一个奇怪的问题。考虑以下(riot.js 框架的一部分):

var s = "{JSON.stringify(\\{ amount: Math.floor(reward.amount) \\})}";
var s1 = s.replace(/\\{/g, '\uFFF0');

在 localhost 上运行此代码时,它运行良好。但是在我们的暂存环境中运行时,\{ 片段不会被 \uFFF0(代码点 65520)替换,而是被 \uFFFD(代码点 65533)替换。这意味着稍后尝试将特殊字符替换回 { 时会失败。

replace 方法是浏览器的原生方法。包含 HTML(字符串是 DOM 属性)和 javascript 的文件由服务器返回,并带有 charset=utf-8 标头并按此编码。在暂存环境中,它与其他文件捆绑在一起(虽然不是压缩或修改),并且仍然以 utf-8 编码。
我不知道为什么会这样,或者为什么不系统。

【问题讨论】:

    标签: javascript replace uglifyjs riot.js


    【解决方案1】:

    \uFFFD,或可视化:�,是浏览器向您显示字符串中的字符是无效字符的方式。

    字符串本身仍将包含\uFFF0,但由于未定义该字符,因此浏览器会呈现�。

    对我来说,在控制台中,
    谷歌浏览器显示:￰(白框,黑边,带问号)。
    Safari 显示:￰(白框,黑边,带问号)。
    Internet explorer 显示:￰(白框,黑边)。
    边缘显示:￰(白框,黑边)。
    Firefox 显示:没有。

    它们都是相同的字符串。只是不同的视觉表示,具体取决于浏览器。

    var s = "{JSON.stringify(\\{ amount: Math.floor(reward.amount) \\})}",
        s1 = s.replace(/\\{/g, '\uFFF0'),
        charCode = s1.charCodeAt(16);
    
    document.write(charCode + ' ' + String.fromCharCode(charCode));
    document.write('|');
    document.write('￰'.charCodeAt(0));
    document.write('|');
    document.write('x'.replace('x', '\uFFF0').charCodeAt(0));

    (对我来说,在 Chrome 中,这个 sn-p 向我显示:65520 ￰|65520|65520

    【讨论】:

    • 好吧,s1.charCodeAt(17) 返回 65533;不是 65520,所以字符串确实包含替换字符而不是预期的字符。此外,s1.replace('\uFFF0', '{') 什么也不做,这意味着字符串不包含 '\uFFF0' 字符。再说一次,只有从远程环境执行时,在本地工作正常。
    • 该问题仅在 IE11 中出现,仅在从特定环境执行代码时出现。这就是我包含服务器/编码细节的原因。
    • 我的意思是浏览器不会替换字符。在 IE11 中运行我的 sn-p 得到与 chrome 相同的结果,除了第二个数字是 65533,因为字符串中的实际字符是 而不是 。这可能不是浏览器问题,而是其他问题。
    【解决方案2】:

    我将问题追溯到 UglifyJs。默认情况下,它将转义的 unicode 字符替换为实际字符。所以:

    var s1 = s.replace(/\\{/g, '\uFFF0');
    

    在捆绑文件中变成这个:

    var s1 = s.replace(/\\{/g, '￰');
    

    在使用 source map 调试时不可见,并且在 IE11 中表现不佳。

    解决方案是在 Uglify 中添加ASCIIOnly: true 选项。
    注意:Uglify 文档将此选项称为ascii-onlyascii_only,但真正考虑的唯一变体是ASCIIOnly

    【讨论】:

      猜你喜欢
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 2014-02-15
      • 2010-10-03
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多