【问题标题】:Are single quotes allowed in HTML?HTML中是否允许使用单引号?
【发布时间】:2010-09-21 08:41:53
【问题描述】:

我是在 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 时会遇到问题?

【问题讨论】:

标签: html


【解决方案1】:

这类似于When did single quotes in HTML become so popular?the specification 始终允许 HTML 中属性周围的单引号。我认为任何浏览器都不会理解它们。

【讨论】:

  • 我需要在这里提到的一件事是,一些 HTML 客户端(不是必需的浏览器)在单引号方面存在兼容问题。一个奇怪的例子是,在 Hotmail 中,如果您使用 &lt;img src='cid:xxx' ... /&gt; 显示内联图像,它根本不会出现,因为内容 ID 被忽略了。您必须改用`。
【解决方案2】:

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

XML standard 允许在属性值周围使用单引号和双引号。

XHTML 标准没有说任何改变这一点,但相关部分指出attribute values must be quoted 在示例中使用双引号,这可能导致了这种混淆。这个例子只是指出 XHTML 中的属性值必须满足 XML 中属性值的最低标准,这意味着它们必须被引用(与不关心的纯 HTML 相反),但并不限制您使用单个或双引号。

当然,您总是有可能遇到不符合标准的解析器,但是当这种情况发生时,无论如何,所有的赌注都没有了。所以最好只遵守规范所说的。毕竟,这就是我们有规范的原因。

【讨论】:

  • +1 用于指向 XML 标准的链接。我知道这是一个旧线程,但为了完整起见,人们应该特别注意标准中的AttValue 语法规范。如果您可以阅读 EBNF(非常类似于正则表达式),您会发现它允许使用单引号和双引号来分隔属性。
  • 但是 HTML 是基于 SGML(它是基于 XML 的 XHTML),所以引用 XML 规范不是很有用……
  • 真正的困惑是属性值中的单引号还是双引号总是需要转义。似乎如果您在属性值周围使用双引号,那么您必须转义双引号,而不是单引号。相反,如果您在属性值周围使用单引号,那么您必须转义单引号,而不是双引号。我认为这就是允许两者的全部意义。如果您的值中有很多双引号,则可以通过在整个值周围使用单引号来避免转义它们,反之亦然。
  • 事实上,如果您使用 XHTML 文档模式,您将遇到 Javascript 解释器问题,它会尝试强制任何 Javascript 创建的 HTML 使用双引号, 用未转义的双引号破坏属性。几年前我在 Firefox 和 IE 中遇到了这个问题。
【解决方案3】:

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

那个人错了。

【讨论】:

  • 不一定。我可以在几分钟内创建一个无法识别 HTML 字段单引号的浏览器。当然,还有很多它不认识的……;P
  • @LightnessRacesinOrbit "你的意思是这个浏览器不支持 CSS 是什么意思?!"
  • ... 或更重要的是,“那个浏览器(它没有)是死肉”。 :P
  • @LightnessRacesinOrbit - 但你有吗?似乎任何有足够动力制作整个浏览器的人都会额外投入 5 分钟以使其接受单引号。
【解决方案4】:

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

嗯,我在打字时往上看,发现 Adam N 传播了同样的信念。如果他能支持他的断言,我会收回我写的内容...... AFAIK,XML 是不可知论者,并且接受这两种引用。我什至尝试并验证了一个只有单引号的 XHTML 页面。

【讨论】:

    【解决方案5】:

    唯一的问题是数据进入 TEXT INPUT 字段。考虑

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

    同理:

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

    你无法逃避,你必须使用htmlspecialchars

    【讨论】:

    • 你可以这样做:&lt;input value='it&amp;apos;s gonna break'/&gt;
    • 我认为我们可以选择使用单引号或双引号的原因是避免在这种情况下必须转义字符。如果您的值中只有双引号,请用单引号将其括起来以避免必须像这样转义双引号:&lt;input value="it's not gonna break"/&gt;,反之亦然:&lt;input value='i say - "this is not gonna be trouble"'/&gt;
    • @Triynko 是对的。此外:对于内容,首先考虑使用“哑引号”,而是“印刷引号”:彼得的酒吧,而不是彼得的酒吧。 ☞en.wikipedia.org/wiki/Quotation_mark#Quotation_marks_in_English
    • 这个答案是唯一明智的建议。始终使用htmlspecialchars。变量插值是很好的语法糖,但硬币的另一面是它很容易导致难以发现的 XSS 漏洞。
    • “你无法逃避……”好吧,我想说 HTML 实体 一种逃避的方式。
    【解决方案6】:

    因为我想在更新的规范版本中找到这方面的信息,我花了很长时间才找到它,这里是:

    来自

    HTML

    生活标准 — 最后更新时间为 2021 年 9 月 17 日

    [...]

    13.1.2.3 属性

    单引号属性值语法

    属性名称,后跟零个或多个 ASCII 空格,后跟单个 U+003D 等号字符,后跟零个或多个 ASCII 空格,后跟单个 U+0027 撇号字符 ('),然后是属性值,除了上述对属性值的要求外,它不得包含任何文字 U+0027 撇号字符 ('),最后跟第二个单个 U+0027 撇号字符 (')。
    在以下示例中,type 属性使用单引号属性值语法给出:

    <input type='checkbox'>
    

    如果使用单引号属性语法的属性后跟另一个属性,则必须用 ASCII 空格分隔两者。

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

    【讨论】:

      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

        我在 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')};
        

        【讨论】:

          【解决方案9】:

          最近我遇到了 Google 搜索优化问题。如果有单引号,它似乎不会抓取链接的页面。

          【讨论】:

          • 这只是在&lt;a href=''&gt; 属性中吗?
          【解决方案10】:

          ... 或者只使用 heredocs。那你就不用担心转义了,除了END

          【讨论】:

          • 相信你指的是heredoc capability in PHP
          • 不知道为什么这个答案在原始问题的上下文中被否决。它没有直接回答双引号单引号问题,但它确实解决了导致 OP 首先偏爱单引号的 php 转义问题。然而,它可以与一个使用示例有关。
          【解决方案11】:

          单引号适用于 HTML,但它们不能生成有效的 XHTML,如果有人使用仅支持 XHTML 而不支持 HTML 的浏览器,这可能会出现问题。我不相信任何这样的浏览器存在,尽管可能有一些用户代理确实需要严格的 XHTML。

          【讨论】:

          • 更糟糕的是人们编写 HTML 页面但将它们标记为 XHTML,因为它“更好”。幸运的是,这种时尚似乎正在走下坡路。
          • 我不相信这个关于 XHTML 的说法是正确的。 " 和 ' 在 XML 中都是可接受的,并且 W3C 验证器接受带有单引号属性的 XHTML 文档。也许这可能与 XHTML 消除了在 HTML 中合法的未引用属性相混淆?
          • 除非您将页面作为 text/xhtml 而非 text/html 提供,否则浏览器会将其呈现为 HTML,因此将应用 HTML 规则。不管怎样,w3C 的一项原则是不破坏网络。因为它现在有效,所以明天可能会有效。
          • XHTML 要求页面是格式良好的 XML,而 XML 允许在属性周围使用双引号或单引号。
          • @SoftwareMonkey 实际上,你需要application/xhtml+xmlapplication/xml
          猜你喜欢
          • 2011-04-29
          • 2021-07-02
          • 2010-12-16
          • 2012-05-07
          • 1970-01-01
          • 1970-01-01
          • 2015-12-27
          • 1970-01-01
          相关资源
          最近更新 更多