String.replace IE11中的奇怪行为

String.replace strange behaviour in IE11

本文关键字:replace IE11 String      更新时间:2023-09-26

我在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进行编码。
我不知道为什么它会这样,或者为什么它不是系统的。

'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中,这个片段向我显示:65520 ￰|65520|65520

我追踪到了UglifyJs的问题。默认情况下,它将转义的unicode字符替换为实际字符。因此:

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

在捆绑文件中变成这样:

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

当使用源映射进行调试时,它是不可见的,并且在IE11中表现不佳。

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