此问题相关信息(我不放在最前面,似乎有些朋友会找不到的样子.)
IE10+, Safari5.17+, Firefox4.0+,Opera12+, Chrome7+ 已经按新标准实现. 所以就没有这个问题了.
参考标准 : http://www.w3.org/html/ig/zh/wiki/HTML5/tokenization 新标准明确提到,如果实体后面遇到的不是;且下一个是= 那么就不处理的.就是为了解决这个坑爹的问题的.
我们来看demo :
<a href=”http://www.baidu.com?a=1®=2®_a=3″ >悲剧</a>
部分浏览器(对应上面已经按新标准实现的版本之下的,各个浏览器.)
点上面的链接, 会自动把 ® 转意成® (部分浏览器会自动对转意后的字符进行编码) .
这个bug.的本质,就是当HTML中出现相关HTML实体(HTML character entity)时.就自动转意处理了. 所以理论上, 用脚本,动态创建的资源则没有这个问题,比如 new Image().src = ‘http://www.baidu.com?a=1®=2’; 甚至动态创建的iframe.亦如此.
IE9- 有两个问题比其他浏览器更严重:
1. 用脚本跳转当前页比如location.href = xxx,或 location.replace(xxx) .又或者是调用window.open(xxx);如果查询字符串中包含这些html实体, 仍然会触发这个问题…
2. ,参见标准, 你会知道实体+”其他字符” , “其他字符中”,哪些与实体连接在一起,是没有这个问题的. 比如 ®a , ®1 其中a, 1 与 ® 连接就不会有这种问题,从标准角度,甚至是 ®_a 也不应有问题. 但是IE9-又一次打败了我们. 至于其他特殊字符如 # ~ 等.在各个浏览器中表现各异. 考虑我们在设计字段名时,不大可能出现那些字符.我们也不再纠结其他浏览器在此处实现的差异.
所以,理论上,这个问题应该是后端的同学,在输出html时.更加要注意的问题. 而前端同学,要注意的则是跳转或弹窗时的url中是否有相关的字段包含一个无分号即为html实体的情况.
至于IE为啥这么特殊…我也没想明白…
那么,无论后端同学也好,前端同学也罢,我们可能更改已经定好的字段成本比较高. 所以其实最妥善的办法,应该是这样子: (感谢 @辰光未然 的提醒.)
1 2 3 4 | var fixURL = function (url) { return url.replace(/&/g,'&'); }; //使用fixURL 去替换url中的&.然后再输出给html, 或者跳转链接,又或者弹窗... 当然,前端的同学在js代码中之所以要这样做.主要是受IE的拖累... |
那么大概,很多HTML 实体都会出问题:
这个表里, 没有分号结尾的,都是隐患… 也就是下面这106个: (感谢 @kenny 提供的最新的list 地址. 我花了点时间写了个脚本.把需要处理的,都抓了出来.)
我们可以用下面这个脚本来帮忙做检测 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | var checkURL = function () { var list = [ //106 'Á', 'á', 'Â', 'â', '´', 'Æ', 'æ', 'À', 'à', '&', '&', 'Å', 'å', 'Ã', 'ã', 'Ä', 'ä', '¦', 'Ç', 'ç', '¸', '¢', '©', '©', '¤', '°', '÷', 'É', 'é', 'Ê', 'ê', 'È', 'è', 'Ð', 'ð', 'Ë', 'ë', '½', '¼', '¾', '>', '>', 'Í', 'í', 'Î', 'î', '¡', 'Ì', 'ì', '¿', 'Ï', 'ï', '«', '<', '<', '¯', 'µ', '·', ' ', '¬', 'Ñ', 'ñ', 'Ó', 'ó', 'Ô', 'ô', 'Ò', 'ò', 'ª', 'º', 'Ø', 'ø', 'Õ', 'õ', 'Ö', 'ö', '¶', '±', '£', '"', '"', '»', '®', '®', '§', '­', '¹', '²', '³', 'ß', 'Þ', 'þ', '×', 'Ú', 'ú', 'Û', 'û', 'Ù', 'ù', '¨', 'Ü', 'ü', 'Ý', 'ý', '¥', 'ÿ' ]; return function (url) { var l = list; var i = l.length; var matchIndex; var current; var nextchar; var errors = []; for (; i--;){ matchIndex = url.indexOf(l[i]); current = l[i]; if(matchIndex > -1){ if((current === '&' || current === '&') && url.charAt(matchIndex + 4) === ';'){ //如果是 & 或 & 我们就认为是故意要输出 & ,比如是一个调用fixURL方法修正过的URL.里面的& 会被我们替换为 amp; //所以,我们要跳过它,去检查后面. continue; } nextchar = url.charAt(matchIndex + current.length); if(!/[a-zA-Z0-9]/.test(nextchar)){ //此处我们只要发现任意一个 ,如 ®后面紧随字符不在 a-z,A-Z,0-9范围内.就算有问题. //这样处理实际和标准的细节以及浏览器实现有细微差异. 但是本着任何浏览器来跑case,都能发现潜在威胁的原则.和实现复杂度的考虑. // 我们姑且粗暴的这样处理了. 似乎还不错. errors.push(current + nextchar); } } } if(errors.length){ throw Error('contains : \n' + errors.join('\n')); } }; }(); |
test case 1:
1 2 3 4 | var url = '//www.baidu.com?a=1&=2<=3®=4'; document.onclick = function () { //IE9-好了.证明我们的修正是ok的了. window.open(fixURL(url)) }; |
test case 2:
1 2 3 4 5 6 | var url = '//www.baidu.com?a=1&=2<=3®=4'; try{ checkURL(url); }catch(e){ alert(e.message) } |
以上为转载,转载来源:http://www.cnblogs.com/_franky/archive/2012/09/28/2706512.html
What’s the difference between this HTML snippet:
1 | <a href="http://www.google.com/search?q=html&foo=0">foo=0</a> |
and this?
1 | <a href="http://www.google.com/search?q=html©=0">copy=0</a> |
Both of them look like simple Google searches (though they could have been anything; Google is just an example). One of them appends an extra “&foo=0″ to the end of the URL; the other appends “©=0″ instead.
Only the second snippet is valid in HTML 4.01 Strict, but that snippet doesn’t work the way you might expect. Neither snippet is valid in XHTML.
Give up? Click on these:
The first URL searches for “html,” but the other URL searches for “html©=0.”
Two weird things are happening here.
- Note that “©” is an HTML entity for the copyright symbol “©.” It would have been more obvious if the URL had used a semicolon, like this:1<a href="http://www.google.com/search?q=html©=0">copy;=0</a>
or if we’d used a more traditional HTML entity like this:
1<a href="http://www.google.com/search?q=html"=0">quot;=0</a> - The second weird thing is a quirk in the HTML specification on character references:
Note. In SGML, it is possible to eliminate the final “;” after a character reference in some cases (e.g., at a line break or immediately before a tag). In other circumstances it may not be eliminated (e.g., in the middle of a word). We strongly suggest using the “;” in all cases to avoid problems with user agents that require this character to be present.
As a result, all modern browsers (FF3, IE7, Opera 9, Safari 3.1) will helpfully notice possible entities like “©” and “<” and replace them with “©” and “<” … they assume you forgot the semicolon. This applies to all of the HTML entities, even the obscure ones like &empty “∅”, ¬ “¬”, ® “®”, &sub “⊂”, and &lang “⟨”. (Bizarrely, &Copy is left alone as “&Copy” but © is replaced with “©”.)
We think there are two valuable lessons to learn from this story. The first lesson you may already know:
- The correct way to write an URL with a query parameter is to HTML escape the URL, replacing all &s with & like this:1<a href="http://www.google.com/search?q=html©=0">copy=0</a>
That’s also the only way to make the snippet XHTML compliant.
- Don’t use URL query parameters whose names are HTML entities. Never create a web service that accepts a query parameter like “&lang=en”. After all, there’s no way to know when your users might want to copy & paste your URLs into a blog, forum, or HTML email. Even if developers are clever enough to HTML escape href links, not everyone will be, and you can save everybody some trouble by avoiding the dangerous entities altogether.
以上为转载,来源|source:http://blog.redfin.com/devblog/2008/10/url_query_parameters_and_html_entities_the_case_of_the_missing_semicolon.html