jQuery attr()函数用html特殊字符打破html?

时间:2012-12-12 19:50:38

标签: javascript jquery html

请查看以下代码:

http://jsfiddle.net/htdTg/2/

在第一个链接中有一个title属性,其中包含html特殊字符<,后跟“!” (实际上跟随哪个角色并不重要)。 当我们使用jQuery的attr()函数获取该title属性的值时,html被破坏(您可以看到,只要以下文本也缺失,就不会打印“<”字符。

在第二个链接中唯一的区别是我在<之后添加了一个空格,现在它按预期工作。

您认为这是jQuery中的错误还是我不明白?

PS。如果您认为我做了一些奇怪的事情 - 它只是来自某个工具提示插件的一些代码。

HTML:

<a href="#" title="<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>">This is a link</a><br>
<a href="#" title="<div style='color:red'>This is the less than sign: &lt; ! Now you know it?</div>">This is a link</a><br>​

jQuery的:

$('a').each(function() {
    $('body').append($(this).attr('title')); });

// just to exclude that it's append() function's fault :)
$('body').append("<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>");​

6 个答案:

答案 0 :(得分:5)

这非常有趣。我查找了title attribute中的文字,参考文献说明了:

  

用户代理应按如下方式解释属性值:

     
      
  1. 用字符替换字符实体
  2.   
  3. 忽略换行,
  4.   
  5. 用一个空格替换每个回车或标签。
  6.   

显然,这是预期的行为。浏览器将&lt;解析为<,可能会被jQuery解释为HTML。

你也应该逃避&符号:

&amp;lt;

演示:http://jsfiddle.net/htdTg/9/

更好的演示:http://jsfiddle.net/PsZeY/6/

答案 1 :(得分:3)

为什么会发生这种情况?

这种情况正在发生,因为&lt;! Now you know it? </div>已转换为<! Now you know it? </div-->

根据HTML标准 <!>评论结构的开头和结尾。请注意,这是评论结构不评论。因此,除非得到结束分隔符>,否则将其余部分转换为注释。

来自W3C

<!-- this is a comment -->
<!-- and so is this one,
    which occupies more than one line -->
     

标记声明打开分隔符(<!)和注释打开分隔符(--)之间不允许有空格,但在注释关闭分隔符之间是允许的( --)和标记声明关闭分隔符(“&gt;”)。常见错误是在注释中包含一串连字符(---)。作者应避免在评论中放置两个或多个相邻的连字符。

同样在here

  

SGML中注释声明的语法是

 comment declaration =
    MDO ("<!"), (comment, ( s | comment )* )?, MDC (">")
 comment =
    COM ("--"), SGML character*, COM ("--")

如何解决?

你已经知道了。使用&amp;替换&。所以请写&amp;lt;!而不是&lt;!。这将使&lt;附加到body元素而不是<!,这是注释结构打开。

答案 2 :(得分:1)

我不确定你是在问这个问题还是实际上是在寻找问题的解决方案。如果是后者,那么奇怪的是这似乎工作得很好:&amp;lt;

更新的代码:

HTML:

<a href="#" title="<div style='color:red'>This is the less than sign: &amp;lt;! Now you know it?</div>">This is a link</a><br>
<a href="#" title="<div style='color:red'>This is the less than sign: &amp;lt; ! Now you know it?</div>">This is a link</a><br>​

jQuery的:

$('a').each(function() {
    $('body').append($(this).attr('title')); });

// just to exclude that it's append() function's fault :)
$('body').append("<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>");​

更新了小提琴:http://jsfiddle.net/htdTg/3/

答案 3 :(得分:1)

文本没有遗漏问题是它被评论,因为&lt;!<!相同,而<!--被翻译为html(不知道为什么) <div style='color:red'>This is the less than sign: <!-- Now you know it? --></div> <div style='color:red'>This is the less than sign: < ! Now you know it?</div> 中的评论。

如果你检查你的HTML,你会看到以下内容。

{{1}}

答案 4 :(得分:1)

在这种情况下......

title="<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>"

&lt;!转换为<!,这是HTML注释的开头,也就是它无法在浏览器窗口中呈现的原因。

对于所有情况,您不应该在属性中包含HTML实体。请改用它......

title="&lt;div style='color:red'&gt;This is the less than sign: &amp;lt;! Now you know it?&lt;/div&gt;"

http://jsfiddle.net/htdTg/5/

如果您想保留HTML实体,请使用&lt;div&gt; 处理作为<div>。或者,&amp;lt;div&amp;gt;实际上会在浏览器窗口中呈现 <div>

请参阅:http://jsfiddle.net/htdTg/8/

因此,如果您希望浏览器实际显示<!,请使用此代码:&amp;lt!

答案 5 :(得分:1)

没有什么是错的..

问题是必须对html内部属性进行编码。您已将<编码为&lt;,这意味着它将被视为<

因此.attr()将返回纯<字符,而不是编码..

它没有显示的原因是.append,如果它认为html中有html,它将尝试解析html ..它找到<!文本并认为它是html评论。 实际上这是由浏览器直接完成的


如果你看一下

var e = document.createElement('div');
e.innerHTML = '<!';
console.log(e.innerHTML);

您将看到div设置为<!后的内部HTML为<!---->

这就是浏览器如何解释这段代码..它与jQuery无关。