### 导航
- [索引](# "总目录")
- [下一页](# "安全注意事项") |
- [上一页](# "Flask 中的设计决策") |
- [Flask 0.10.1 文档](#) »
# HTML/XHTML 常见问题
Flask 文档和示例应用使用 HTML5 。你可能会注意到,在许多情况下当结束标签是可选的时候,并不使用它们,这样 HTML 会更简洁且加载更迅速。因为在开发者中,关于 HTML 和 XHTML 有许多混淆,本文档试图回答一些主要的疑问。
### XHTML 的历史
一段时间, XHTML 的出现欲取代 HTML 。然而,Internet 上几乎没有任何实际的 XHTML (用 XML 规则处理的 HTML )网站。这种情况有几个主要的原因。其一是 Internet Explorer 缺乏对 XHTML 妥善的支持。 XHTML 规范要求 XHTML必须由 MIME 类型 application/xhtml+xml 来承载,但是 Internet Explorer拒绝读取这个 MIME 类型下的文件。
虽然配置 Web 服务器来提供正确的 XHTML 相对简单,但很少有人这么做。这可能是因为正确地使用 XHTML 会是一件痛苦的事。
痛苦的最重要的原因之一是 XML 苛刻的(严格而残忍)错误处理。当 XML 处理中遭遇错误时,浏览器会把一个丑陋的错误消息显示给用户,而不是尝试从错误中恢并显示出能显示的。web 上大多数的 (X)HTML 生成基于非 XML 的模板引擎(比如Flask 所使用的 Jinja)并不会防止你偶然创建无效的 XHTML 。也有基于 XML 的模板引擎,诸如 Kid 和 流行的 Genshi,但是它们经常具有更大的运行时开销,并且不能直接使用,因为它们要遵守 XML 规则。
大多数用户,不管怎样,假设它们正在正确地使用 XHTML 。他们在文档的顶部写下一个 XHTML doctype 并且闭合了所有必要闭合的标签( 在 XHTML 中 <br> 要写为 <br/> 或 <br></br> )。然而,即使文档可以正确地通过 XHTML验证,真正决定浏览器中 XHTML/HTML 处理的是前面说到的,经常不被正确设置的MIME 类型。所以有效的 XHTML 会被视为有效的 HTML 处理。
XHTML 也改变了使用 JavaScript 的方式。要在 XHTML 下正确地工作,程序员不得不使用带有 XHTML 名称空间的 DOM 接口来查询 HTML 元素。
### HTML5 的历史
HTML5 规范的开发在 2004 年就以 “Web 应用1.0”之名由网页超文本技术工作小组(Web Hypertext Application Technology Working Group),或 WHATWG(由主要的浏览器供应商苹果、 Mozilla 以及 Opera 组成)启动了,目的是编写一个新的改良的HTML 规范,基于现有的浏览器行为,而不是不切实际和不向后兼容的规范。
例如,在 HTML4 中 <title/Hello/ 理论上与 <title>Hello</title> 处理得完全相同。然而,由于人们已然使用了诸如 <link/> 的 XHTML-like 标签,浏览器供应商在规范语法之上实现了 XHTML 语法。
在 2007 年,这个标准被 W3C 收入一个新的 HTML 规范,也就是 HTML5 。现在,随着 XHTML 2 工作组解散和 HTML5 被所有主流浏览器供应商实现,XHTML 正在失去吸引力。
### HTML vs. XHTML
下面的表格给你一个 HTML 4.01 、 XHTML 1.1 和 HTML5 中可用特性的简要综述。(不包括 XHTML 1.0 ,因为它被 XHTML 1.1 和几乎不使用的 XHTML5 代替 )
| | HTML4.01 | XHTML1.1 | HTML5 |
|-----|-----|-----|-----|
| <tag/value/ == <tag>value</tag> | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png)[[1]](#) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) |
| 支持 <br/> | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png)[[2]](#) |
| 支持 <script/> | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) |
| 应该使用的 MIME 类型: text/html | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png)[[3]](#) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) |
| 应该使用的 MIME 类型:application/xhtml+xml | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) |
| 严格的错误处理 | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) |
| 内联 SVG | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) |
| 内联 MathML | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) |
| <video> 标签 | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) |
| <audio> 标签 | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) |
| 新的语义标签,比如 <article> | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![No](https://box.kancloud.cn/2016-03-26_56f6a4a8b4dc2.png) | ![Yes](https://box.kancloud.cn/2016-03-26_56f6a4a8a2e1d.png) |
| [[1]](#) | 这是一个从 SGML 中继承过来的鲜为人知的特性。由于上述的原因,它通常不被浏览器支持。 |
|-----|-----|
| [[2]](#) | 这用于兼容生成 <br> 之类的服务器代码。它不应该在新代码中出现。 |
|-----|-----|
| [[3]](#) | XHTML 1.0 是考虑向后兼容,允许呈现为 text/html 的最后一个 XHTML 标准。 |
|-----|-----|
### “严格”意味着什么?
HTML5 严格地定义了处理规则,并准确地指定了一个浏览器应该如何应对处理中的错误——不像 XHTML,只简单声明将要中断解析。一些人因显然无效的语法仍生成期望中结果而困惑(比如,缺失结尾标签或属性值未用引号包裹)。
这些工作是因为大多数浏览器遭遇一个标记错误时的错误处理是宽容的,其它的实际上也指定了。下面的结构在 HTML5 标准中是可选的,但一定被浏览器支持:
- 用 <html> 标签包裹文档。
- 把页首元素包裹在 <head> 里或把主体元素包裹在 <body> 里。
- 闭合 <p>, <li>, <dt>, <dd>, <tr>,<td>, <th>, <tbody>, <thead> 或 <tfoot> 标签。
- 用引号包裹属性值,只要它们不含有空白字符或其特殊字符(比如 < 、> 、 ' 或 " )。
- 需要布尔属性来设定一个值。
这意味着下面的页面在 HTML5 中是完全有效的:
~~~
<!doctype html>
<title>Hello HTML5</title>
<div class=header>
<h1>Hello HTML5</h1>
<p class=tagline>HTML5 is awesome
</div>
<ul class=nav>
<li><a href=/index>Index</a>
<li><a href=/downloads>Downloads</a>
<li><a href=/about>About</a>
</ul>
<div class=body>
<h2>HTML5 is probably the future</h2>
<p>
There might be some other things around but in terms of
browser vendor support, HTML5 is hard to beat.
<dl>
<dt>Key 1
<dd>Value 1
<dt>Key 2
<dd>Value 2
</dl>
</div>
~~~
### HTML5 中的新技术
HTML5 添加了许多新特性来使得 Web 应用易于编写和使用。
- <audio> 和 <video> 标签提供了不使用 QuickTime 或 Flash 之类的复杂附件的嵌入音频和视频的方式。
- 像 <article> 、 <header> 、 <nav> 以及 <time> 之类的语义化元素,使得内容易于理解。
- <canvas> 标签,支持强大的绘图 API ,减少了服务器端生成图像来图形化显示数据的必要。
- 新的表单控件类型,比如 <inputtype="data"> 使得用户代理记录和验证其值更容易。
- 高级 JavaScript API ,诸如 Web Storage 、 Web Workers 、 Web Sockets 、地理位置以及离线应用。
除此之外,也添加了许多其它的特性。 Mark Pilgrim 即将出版的书[Dive Into HTML5](http://www.diveintohtml5.org/) [http://www.diveintohtml5.org/] 是 HTML5 中新特性的优秀入门书。并不是所有的这些特性已经都被浏览器支持,无论如何,请谨慎使用。
### 应该使用什么?
一般情况下,答案是 HTML 5 。考虑到 web 浏览器最新的开发,几乎没有理由再去使用 XHTML 。总结上面给出的原因:
- Internet Explorer (令人悲伤的是目前市场份额处于领先) 对 XHTML 支持不佳。
- 许多 JavaScript 库也不支持 XHTML ,由于它需要复杂的命名空间 API 。
- HTML 添加了数个新特性,包括语义标签和期待已久的 <audio> 和<video> 标签。
- 它背后获得了大多数浏览器供应商的支持。
- 它易于编写,而且更简洁。
对于大多数应用,使用 HTML5 无疑比 XHTML 要好。
© 版权所有 2013, Armin Ronacher.
- 欢迎使用 Flask
- 前言
- 给有经验程序员的前言
- 安装
- 快速入门
- 教程
- 介绍 Flaskr
- 步骤 0: 创建文件夹
- 步骤 1: 数据库模式
- 步骤 2: 应用设置代码
- 步骤 3: 创建数据库
- 步骤 4: 请求数据库连接
- 步骤 5: 视图函数
- 步骤 6: 模板
- 步骤 7: 添加样式
- 福利: 应用测试
- 模板
- 测试 Flask 应用
- 记录应用错误
- 配置处理
- 信号
- 即插视图
- 应用上下文
- 请求上下文
- 用蓝图实现模块化的应用
- Flask 扩展
- 与 Shell 共舞
- Flask 代码模式
- 大型应用
- 应用程序的工厂函数
- 应用调度
- 使用 URL 处理器
- 部署和分发
- 使用 Fabric 部署
- 在 Flask 中使用 SQLite 3
- 在 Flask 中使用 SQLAlchemy
- 上传文件
- 缓存
- 视图装饰器
- 使用 WTForms 进行表单验证
- 模板继承
- 消息闪现
- 用 jQuery 实现 Ajax
- 自定义错误页面
- 延迟加载视图
- 在 Flask 中使用 MongoKit
- 添加 Favicon
- 数据流
- 延迟请求回调
- 添加 HTTP Method Overrides
- 请求内容校验码
- 基于 Celery 的后台任务
- 部署选择
- mod_wsgi (Apache)
- 独立 WSGI 容器
- uWSGI
- FastCGI
- CGI
- 聚沙成塔
- API
- JSON 支持
- Flask 中的设计决策
- HTML/XHTML 常见问题
- 安全注意事项
- Flask 中的 Unicode
- Flask 扩展开发
- Pocoo 风格指引
- Python 3 支持
- 升级到最新版本
- Flask Changelog
- 许可证
- 术语表