打开任意页面,也就是让浏览器初始化一个window。然后在地址栏中输入 javascript:'中文'
或者 javascript:'\u4e2d\u6587'
(Chrome与IE9下直接把上面的code粘贴进地址栏就会把 javascript:
吃掉)
Chrome、Firefox、Safari、IE6如下显示
IE7,8,9 直接乱码
为了弄清楚乱码究竟是什么东西,写了如下代码,复制到地址栏运行
javascript:'<script>a=("\u4e2d\u6587");l=a.length;r=[];for(i=0;i<l;i++){r.push(a.charCodeAt(i).toString(16));}alert(r.join(","))</script>'
格式化一下供大家参观
var s="\u4e2d\u6587"; var l=s.length; var r=[]; for(var i=0;i<l;i++){ r.push(s.charCodeAt(i).toString(16)); } alert(r.join(","));
这时 IE 7,8,9 有如下诡异的返回
附Firefox正常返回
跪求大牛分析原因及提供解决方法。
补充一个测试
javascript:window.document.title
IE 7,8,9 又逆天了………PHP中文网2017-04-10 12:46:00
测试发现,实际上IE把地址栏javascript的返回值按ASCII码直接显示在页面上了。由于js内部都是utf-16编码,一个字符2个字节,中文对应的是 0x2d 0x4e 0x87 0x65, 也就是 "-N�e" 这四个字符。注意由于第三个字符的ascii码大于128,是一个“乱码”。
一个正确的实现(例如Chrome/Firefox/Safari)应当是把输入的字符串都转成utf-16再给js,然后将js输出的字符串都转成页面编码再显示。
根据IE的行为可以推断,IE在这种情况下没有把地址栏执行js的返回值重新转码成页面所需的编码就直接显示在了网页上(也许IE开发者认为在这是feature不是bug...)。但是如果这段代码是在页面源码中执行的话,逻辑就是正确的。
至于为什么 "\u4e2d\u6587" 会被 ie输出“2d, 4e, fffd, 65”,这里的行为我解释不了。"\u4e2d\u6587"这个字符串应当能够被JS识别成2个utf-16编码的字符,但是却被识别成了4个字符(也就是ascii编码的了)。至于为什么会输出2d, 4e 而不是4e, 2d,这是因为x86机器都是小端存储,所以先输出低字节的。但是87为什么会变成fffd我又无法解释了,太蛋疼了。