HTML中允许使用单引号吗?

166

我经常在PHP中使用双引号来插值变量,而不是将字符串连接起来。因此,在生成HTML时,我通常使用单引号来设置标记字段。例如:

$html = "<input type='text' name='address' value='$address'>";

现在,这对我来说比任何其他东西都更易读

$html = "<input type=\"text\" name=\"address\" value=\"$address\">";
或者
$html = '<input type="text" name="address" values="' . $address . '">' ;

根据我简短的搜索,我听说某些浏览器不识别HTML字段中的单引号。因此,我想知道哪些浏览器会有问题识别单引号HTML?


3
可能是使用单引号还是双引号来定义HTML属性更好?的重复问题。 - Brad Werth
11个回答

159

16
这里需要提到一点,就是一些 HTML 客户端(不一定是浏览器)在使用单引号时可能会出现兼容性问题。一个奇怪的例子是,在 Hotmail 中,如果你使用 <img src='cid:xxx' ... /> 来展示内联图片,它将完全不会显示,因为内容 ID 被忽略了。你必须使用 <img src="cid:xxx" ... /> - Earth Engine

58

正如PhiLho所指出的那样,尽管普遍认为单引号在属性值中不允许使用,但这种看法是错误的。

XML标准允许在属性值周围使用单引号或双引号。

XHTML标准没有对此做出任何改变,但相关部分声明属性值必须被引用并在示例中使用了双引号,这可能导致了这种混淆。这个示例仅仅是在指出在XHTML中,属性值必须满足XML中的最低属性值标准,也就是必须被引用(与不关心此事的原始HTML不同),但并没有限制您只能使用单引号或双引号。

当然,也有可能会遇到不符合标准的解析器,但是当发生这种情况时,无论哪种方式都可能会受到影响。因此最好还是遵循规范。毕竟,我们之所以拥有规范,就是为了遵守。


3
感谢提供 XML 标准的链接。尽管这是一个老帖子,但为了完整起见,人们应该特别关注标准中的 AttValue 语法规范。如果你能够阅读 EBNF(非常类似于正则表达式),你会发现它允许使用单引号和双引号来界定属性。 - daiscog
10
但是HTML基于SGML(而XHTML基于XML),因此引用XML规范并不是很有用... - Donal Fellows
真正的困惑在于属性值中的单引号或双引号是否总是需要转义。如果您在属性值周围使用双引号,则必须转义双引号,但不需要转义单引号。相反,如果您在属性值周围使用单引号,则必须转义单引号,但不需要转义双引号。我认为这就是允许两者的全部意义所在。如果您的值中有很多双引号,则可以通过在整个值周围使用单引号来避免转义它们,反之亦然。 - Triynko
事实是,如果您使用XHTML文档模式,您将遇到JavaScript解释器问题,它会尝试强制任何由JavaScript创建的HTML使用双引号,从而破坏其中包含未转义双引号的属性。几年前我在Firefox和IE中都遇到了这个问题。 - user2867288

17

我听到有人说用单引号为HTML字段可能不被每个浏览器识别

那个人是错的。


35
不一定。我可以在几分钟内创建一个浏览器,它不会识别 HTML 字段中的单引号。当然,它还有许多其他内容也无法识别... ;P - Lightness Races in Orbit
1
@LightnessRacesinOrbit “你是什么意思,这个浏览器不支持CSS?!” - BadHorsie
1
更重要的是,“那个(不)支持的浏览器已经凉了”。 :P - ToolmakerSteve
1
@LightnessRacesinOrbit - 但是你做到了吗?似乎任何有动力制作整个浏览器的人都会花费额外的5分钟来使其接受单引号。 - user3413723

12
当我试图在一个更新版本的规范中查找这个信息时,花费了相当长的时间终于找到了,现在分享如下:

来自

HTML

Living Standard — Last Updated 17 September 2021

[...]

13.1.2.3 Attributes

Single-quoted attribute value syntax

The attribute name, followed by zero or more ASCII whitespace, followed by a single U+003D EQUALS SIGN character, followed by zero or more ASCII whitespace, followed by a single U+0027 APOSTROPHE character ('), followed by the attribute value, which, in addition to the requirements given above for attribute values, must not contain any literal U+0027 APOSTROPHE characters ('), and finally followed by a second single U+0027 APOSTROPHE character (').
In the following example, the type attribute is given with the single-quoted attribute value syntax:

<input type='checkbox'>

If an attribute using the single-quoted attribute syntax is to be followed by another attribute, then there must be ASCII whitespace separating the two.

https://html.spec.whatwg.org/multipage/syntax.html#attributes-2

—— https://html.spec.whatwg.org/multipage/syntax.html#attributes-2


7

不要相信互联网上看到的一切......
有趣的是,我刚刚回答了一个类似的问题,有人声称单引号在XHTML中无效......

嗯,我边打字边往上看,看到Adam N也传播了同样的观点。如果他能支持自己的说法,我撤回我写的东西......据我所知,XML是不可知的,并接受两种引号。我甚至尝试并验证了只有单引号的XHTML页面,没有问题。


5

唯一的问题是数据输入到文本输入框中。请考虑以下内容:

<input value='it's gonna break'/>

同理:

<input value="i say - "this is gonna be trouble" "/>

你无法逃避,必须使用 htmlspecialchars


2
你可以这样做:<input value='it's gonna break'/> - rink.attendant.6
4
我们可以使用单引号或双引号的原因是为了避免在某些情况下需要转义特殊字符。如果你的字符串值只包含双引号,可以用单引号将其括起来,这样就不必转义双引号,例如:<input value="it's not gonna break"/>;反之同理:<input value='i say - "this is not gonna be trouble"'/> - Triynko
1
@Triynko是正确的。此外:对于内容,考虑首先不使用“愚蠢的引号”,而是使用“印刷引号”:Peter's bar,而不是Peter's bar。☞https://en.wikipedia.org/wiki/Quotation_mark#Quotation_marks_in_English - Frank N
1
这个答案是唯一明智的建议。始终使用htmlspecialchars。变量插值是很好的语法糖,但其反面是它容易导致难以发现的XSS漏洞。 - Ruud Helderman
“你无法逃避…” 嗯,我认为HTML实体是一种转义的方法。 - Melebius

1

我在HTML中也倾向于使用单引号,而且从未遇到过问题。


1

我在HTML页面中使用了单引号,并将JavaScript嵌入其中,它运行良好。在IE9、Chrome和Firefox中进行了测试,似乎一切正常。

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
        <title>Bethanie Inc. data : geographically linked</title>
        <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js'></script>
        <script src='https://maps.googleapis.com/maps/api/js?v=3.11&sensor=false' type='text/javascript'></script>
        <script type='text/javascript'> 
        // check DOM Ready
        $(document).ready(function() {
            // execute
            (function() {
                /////////////// Addresses ///////////////////
                var locations = new Array();
                var i = 0;
                locations[i++] = 'L,Riversea: Comp Site1 at Riversea,1 Wallace Lane Mosman Park WA 6012'
                locations[i++] = 'L,Wearne: Comp Site2 at Wearne,1 Gibney St Cottesloe WA 6011'
                locations[i++] = 'L,Beachside:Comp Site3 Beachside,629 Two Rocks Rd Yanchep WA 6035'

                /////// Addresses/////////
                var total_locations = i;
                i = 0;
                console.log('About to look up ' + total_locations + ' locations');
                // map options
                var options = {
                    zoom: 10,
                    center: new google.maps.LatLng(-31.982484, 115.789329),//Bethanie  
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: true
                };
                // init map
                console.log('Initialise map...');
                var map = new google.maps.Map(document.getElementById('map_canvas'), options);
               // use the Google API to translate addresses to GPS coordinates 
               //(See Limits: https://developers.google.com/maps/documentation/geocoding/#Limits)
                var geocoder = new google.maps.Geocoder();
                if (geocoder) {
                    console.log('Got a new instance of Google Geocoder object');
                    // Call function 'createNextMarker' every second
                    var myVar = window.setInterval(function(){createNextMarker()}, 700);
                    function createNextMarker() {
                        if (i < locations.length) 
                       {
                            var customer = locations[i];
                            var parts = customer.split(','); // split line into parts (fields)
                            var type= parts.splice(0,1);    // type from location line (remove)
                            var name = parts.splice(0,1);    // name from location line(remove)
                            var address =parts.join(',');   // combine remaining parts
                            console.log('Looking up ' + name + ' at address ' + address);
                            geocoder.geocode({ 'address': address }, makeCallback(name, type));
                            i++; // next location in list
                            updateProgressBar(i / total_locations);


                        } else 
                       {
                            console.log('Ready looking up ' + i + ' addresses');
                            window.clearInterval(myVar);
                        }
                    }

                    function makeCallback(name,type) 
                   {
                        var geocodeCallBack = function (results, status) {
                            if (status == google.maps.GeocoderStatus.OK) {
                                var longitude = results[0].geometry.location.lng();
                                var latitude = results[0].geometry.location.lat();
                                console.log('Received result: lat:' + latitude + ' long:' + longitude);
                                var marker = new google.maps.Marker({
                                    position: new google.maps.LatLng(latitude, longitude),
                                    map: map,
                                    title: name + ' : ' + '\r\n' + results[0].formatted_address});// this is display in tool tip/ icon color
                                   if (type=='E')  {marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png')};

-1

最近我遇到了一些谷歌搜索优化的问题。如果链接中有单引号,它似乎无法爬取关联页面。


1
这只是在<a href=''>属性中吗? - AntonChanning

-2

...或者直接使用heredocs。这样你就不需要担心转义任何东西,只需关注END即可。


我相信你指的是PHP中的heredoc功能 - DavidRR
不确定为什么这个答案被踩了,考虑到原问题的背景。它并没有直接回答双引号和单引号的问题,但是它确实解决了PHP转义问题,这也导致OP更喜欢使用单引号。不过,它还需要一个用法示例。 - AntonChanning

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