单引号和双引号在HTML属性中有什么功能上的区别?

4

sEncodedHref表示一个经过HttpUtility.HtmlAttributeEncode(..)编码的字符串。

像这样生成的html之间是否存在任何功能上的差异:

String.Format(@"<span class='blue' src='{0}'>", sEncodedHref);

与生成的 HTML 相比,它是这样的:

String.Format(@"<span class=""blue"" src=""{0}"">", sEncodedHref);

我一直认为单引号的变体既不太受支持,也不太“安全”,但我很难提供支持这个观点的理由。


请查看此问题:https://dev59.com/DHVC5IYBdhLWcg3wfxU8 - Jared Updike
安全性是一个问题: HtmlAttributeEncode方法仅将引号(“),和符号(&)以及左尖括号(<)转换为等效的字符实体。它比HtmlEncode方法快得多。从HtmlAttributeEncode方法返回的字符串结果应仅用于双引号属性。当使用HtmlAttributeEncode方法处理单引号属性时,可能会出现安全问题。 [来源](http://msdn.microsoft.com/en-us/library/wdek0zbf.aspx) - Jude Allred
2020年有关上述安全问题的更新:HtmlAttributeEncode现在可以处理单引号。 - Jude Allred
6个回答

9
没有功能上的区别。引用W3C关于SGML和HTML的说明
默认情况下,SGML要求所有属性值使用双引号(ASCII十进制34)或单引号(ASCII十进制39)进行界定。当属性值由双引号界定时,可以在属性值中包含单引号,反之亦然。
在某些情况下,作者可能会指定一个没有引号的属性值。该属性值只能包含字母(a-z和A-Z)、数字(0-9)、连字符(ASCII十进制45)、句点(ASCII十进制46)、下划线(ASCII十进制95)以及冒号(ASCII十进制58)。我们建议即使可以消除它们,也应该使用引号。

1
+1。为了符合标准,现在省略引号几乎肯定是一个坏主意。 - stakx - no longer contributing
虽然这是正确的答案,但需要注意的是我给出的例子存在相当大的功能差异:单引号版本容易受到XSS攻击,而双引号版本则不会。 - Jude Allred

4

没有任何实际区别。两种方法都是有效的,尽管双引号更为常用且被推荐使用。


1
为什么双引号会更受青睐?这意味着在某种程度上使用双引号有优势,但实际上并没有。 - molf
因为99.9%的互联网站都在使用它。 - Darin Dimitrov
尽管每个主要的浏览器都可以处理单引号属性值,但其他工具(如语法高亮器等)可能并非如此。 - user123444555621

1
从功能的角度来看,没有任何区别。从安全角度来看则有所不同。当您使用单引号(当这些引号中的文本来自不受信任的来源时)时,黑客更容易进行XSS攻击。但是,我不会只使用双引号来打赌。你最好在属性值上使用适当的编码。
更新:
以下是一个ASP.NET示例:
<input type='button' 
    value='<% = HttpUtility.HtmlEncode(Request["button"]) %>' />

由于使用单引号,这段代码片段更容易被黑客利用。以下是一个例子。当你将下面的文本放入查询字符串的button参数中时,你将有一个成功的XSS攻击:
click' onclick='alert("xss")

就像这样:

mypage.aspx?button?click'%20onclick='alert("xss")

如果我们使用双引号编写代码片段,这次攻击就不会成功:

<input type='button' 
    value="<% = HttpUtility.HtmlEncode(Request["button"]) %>" />

希望这能稍微澄清一些事情。

* 当然,最新的浏览器将检测到这种类型的攻击(称为反射型XSS),但不会检测到当此字符串不是直接来自浏览器时的攻击(称为持久性XSS)。


1
使用单引号执行XSS并不容易。这只意味着不同的字符必须表示为实体。 - Quentin
这很有趣。为什么单引号更“危险”? - stakx - no longer contributing
你误解了 XSS - 这是由 JavaScript 实现的... HTML 本身可以包含 JavaScript,但是 HTML 标签 - 特别是它们的引号 - 与 XSS 和 JavaScript 没有任何关系。 - Andreas Rehm
非常抱歉我没有解释清楚。单引号更加“危险”,因为许多编码器(例如PHP的htmlspecialchars方法(默认配置)和ASP.NET的HttpUtility.HtmlEncode方法)不会对单引号进行编码。当使用这些方法来编码HTML属性值时,同时将值包装在单引号中,它允许黑客向HTML元素中插入新的属性,例如onclickonmouseover。我已经更新了我的答案以展示这样的例子。希望这样更有意义。希望您重新评估您的反对。 - Steven

0

在编程中,对于字符串变量,有时使用单引号会导致“字符文字中的字符太多”错误。例如,在实体框架中定义一个类:

public class DevEnt()
{
public string IMEI {get; set;}
public Datetime {get; set;}
}

然后,当从这个类初始化一个实例的IMEI字段时,

dev=new DevEnt(){
Dev_IMEI="111111",
Date=new DateTime(2015,12,1)
}

使用单引号如Dev_IMEI='111111'会导致错误。

0
就HTML而言,它们没有区别。两者都得到支持。只有在通过其他方式动态输出时,您需要小心适当地转义等等...但这仅涉及您使用的任何脚本语言,而不是您的浏览器。

-2

标准(XHTML)使用双引号,但浏览器仍支持非标准的HTML页面,因此它们仍然可以理解单引号。

您不必转义双引号。


4
通常惯例是使用双引号,标准允许任意一种。 - Quentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接