2012-01-05 32 views
24

在JavaScript字符串文字,一方面转义HTML实体,如果我有在<script>块

<script> 
var s = 'Hello </script>'; 
console.log(s); 
</script> 

浏览器将提前终止<script>块,基本上我得到的页面搞砸了。另一方面,字符串的值可能来自用户(例如,通过先前提交的表单,现在字符串最终以文字的形式插入到<script>块中),因此您可以期望得到任何东西在那个字符串中,包括恶意形成的标签。现在,如果我逃脱字符串文字与ヶ辆()生成的页面时,s的值将包含转义实体字面上,即旨意输出

Hello &lt;/script&gt; 
未在此情况下期望的行为

。正确地转义一个<script>块内JS字符串

一种方式是逃避斜线,如果它遵循左尖括号,或者只是一直逃避斜线,即

var s = 'Hello <\/script>'; 

这似乎是工作的罚款。然后在HTML事件处理程序中出现JS代码的问题,这些问题很容易被破坏,例如,

<div onClick="alert('Hello ">')"></div> 

看起来有效,但在大多数(或全部?)浏览器中打破。这显然需要完整的HTML实体编码。

我的问题是:什么是最好的/标准的做法,适当覆盖上述所有情况 - 即脚本块内的JS,事件处理程序中的JS - 如果您的JS代码可以部分在服务器端生成并且可能潜在包含恶意数据?

+0

可能重复[JavaScript和错误“未打开的元素的结束标记”](http://stackoverflow.com/questions/2744583/javascript-and-error-end-tag-for-element-which-is-not-open ) – Quentin 2012-01-05 21:47:42

回答

36

以下字符可以干扰HTML或JavaScript分析器,并应在字符串进行转义:<, >, ", ', \,&

在使用转义字符的脚本块中,正如你发现的那样,它起作用。级联方法(</scr' + 'ipt>')很难阅读。

var s = 'Hello <\/script>'; 

对于内联JavaScript的HTML,你可以使用实体:

<div onClick="alert('Hello &quot;>')">click me</div> 

演示:http://jsfiddle.net/ThinkingStiff/67RZH/

,在这两个<script>块的工作原理和内联JavaScript是\uxxxx,其中xxxx是方法十六进制字符代码。

  • < - \u003c
  • > - \u003e
  • " - \u0022
  • ' - \u0027
  • \ - \u005c
  • & - \u0026

演示:http://jsfiddle.net/ThinkingStiff/Vz8n7/

HTML:

<div onClick="alert('Hello \u0022>')">click me</div> 

<script> 
    var s = 'Hello \u003c/script\u003e'; 
alert(s); 
</script> 
+3

十六进制转义方法是迄今为止最好的:你不必担心你的字符串在哪里结束于代码中,只需通过一个基本的服务器端函数发送所有内容即可。太棒了,我喜欢它! – mojuba 2012-01-05 23:47:35

-2

大多数人都用这一招:

var s = 'Hello </scr' + 'ipt>'; 
+3

因此,如果代码是在服务器端生成的,我需要寻找

2

这里是我如何做到这一点:

function encode(r){ 
 
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"}) 
 
} 
 

 
var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!'; 
 

 
test.value=encode(myString); 
 

 
testing.innerHTML=encode(myString); 
 

 
/************* 
 
* \x26 is &ampersand (it has to be first), 
 
* \x0A is newline, 
 
*************/
<textarea id=test rows="9" cols="55"></textarea> 
 

 
<div id="testing">www.WHAK.com</div>