Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. HTML5

精通HTML5: 编码

by
Read Time:10 minsLanguages:
This post is part of a series called HTML5 Mastery Class.
HTML5 Mastery: Scoping Rules
HTML5 Mastery: Fragments

Chinese (Simplified) (中文(简体)) translation by Feng Huang (you can also view the original English article)

编码只是那些必须要做对的事情之一. 如果编码错了, 那什么也运行不起来. 如果做对了也不会引起任何人注意. 这使得编码处理令人讨厌。

尽管如此,幸运的是大部分的要做的事都已经准备好了.。 我们只需要确保我们的文件是保存 (和传输) 的是正确的编码。 正确的编码是我们指定的。 它可以是任何东西,只要它包含我们需要的所有的字符和我们想要保持一致的长度。

有三个重要文本 HTML 编码规则:

  1. 使用正确的编码加载内容。
  2. 使用相同的编码传输。
  3. 确保客户端使用相同编码读取内容。

在这篇文章中,我们会深入学习这三个规则的详细内容, 特别是第二和第三个规则. 最后我们将也看看形式编码,这与文本编码没有直接关系,但是有间接关系。 我们将会知道他们为什么会有一些联系。

选择正确的编码

除非我们知道我们的内容应放在一些国家特定的编码否则我们应该只使用UTF-8。 有很多理由让我们只选择utf-8。 它不是在内存中存储的最好形式,但它是是作为数据交换和内容传输的基本形式。 不用想就是用它就对。 不过,一个通常的错误是utf-8不适合保存文件. 在文本没有编码前,我们应该谨慎的选择编码.

Sublime Text用户和许多其它文本编辑器用户也许从来不会遇到错误编码的问题. 因为这些编辑器缺省使用UTF-8保存. 有的编辑器,主要是为 Windows 平台上,使用不同的默认格式,例如,Windows 1252。

即使在Sublime Text,它有很多标准的操作是用来更改文件的编码的。 在我们选择File菜单中使用Save with Encoding来把文件保存为我们想要的编码格式.。 仅此而已!

Saving Text Encoding Sublime TextSaving Text Encoding Sublime TextSaving Text Encoding Sublime Text

原则上每个更高级的编辑器都应该有这样的选项。 有时他们会有一个高级保存按钮.。 例如,微软的 Visual studio 编辑器单击文件菜单中的高级保存选项能弹出一个指定的对话框。

Visual Studio Advanced SaveVisual Studio Advanced SaveVisual Studio Advanced Save

我们应该确保使用正确的编码。 这将为我们的内容和使用的字节数一致。 UTF-8 的主要优点是只需要单个字节,如果我们不使用特殊字符的话。 每个字符最多消耗4个字节。 这是动态的而且UTF-8是文本存储和传输的理想格式。 然而,警告是 UTF-8 不是字符串存在内存中的最佳格式。

控制传输

HTTP 协议传输数据以纯文本格式。 即使我们决定对内容进行编码传输 GZip 或如果我们使用 HTTPS,加密的内容,作为底层内容仍是只是纯文本。 我们已经学到过这不仅仅是纯文本.。 我们总是需要将内容与一些编码得到的文本表示形式相关联。

一条 HTTP 消息被拆分成两个部分。 上半部分称为标头。 由一个空行分隔是下半的部分: 身体。

总有至少两个 HTTP 消息: 请求和其相关联的响应。 这两种类型的消息分享这种结构。 响应的正文是我们想要传输的内容。 请求的正文只是感兴趣的表单提交,我们稍后就会介绍。 如果我们想要提供一些信息编码的内容,我们必须提供一些标头中的信息。

在以下的header告诉接收方正文内容是被称为HTML的指定文本格式,使用 UTF-8 字符集。

也是content-Encoding 头内容。 我们总是很容易混淆的内容编码与内容的实际文本编码。 前者用来指定的整个包,例如 GZip 编码,而后者用作初始设置,例如,解析提供的内容。

如果我们关心这一步的正确性我们必须确保我们的 web 服务器发送正确的报头。 大多数 web 框架提供这种能力。 在 PHP 中,我们可以这样编写:

在 Node.js 我们可能想要使用以下,在 res 是表示请求的变量:

通过的传播的报头的内容可以来决定得HTML文本扫描仪的输入设置. 在前面的例子中,我们使用 utf-8。 等下: 那么初始设定呢! 有许多方法可以重写此设置。 如果实际的内容不是 utf-8,扫描仪可能认识到这一点,并更改的设置。 由字节顺序标记 (称为 BOM) 检测或在内容中查找特定编码的模式,可能会触发这种变化。 与此相反的是,前者看起来认为添加上的.

最后,编码可能会改变我们的 HTML 代码。 而且只能改变一次.

固定的编码

当DOM 构造函数处理meta 标记时,它会寻找 charset的定义.。 只要找到一个,就从中提取字符集。 如果能成功提取并且提取的编码是有效,我们就将提取出的编码设置为扫描字符的新编码。 在这之后编码将被冻结,并且再也不能更改。

这里有一点要注意. 为了检查是否之前的扫描已经完成,我们需要比较已经扫描的字符集和将要扫描的字符集. 因此,我们需要看到是否提前改变编码会发生一些变化.. 如果我们发现变化,我们需要重新启动整个解析过程。 否则整个DOM结构可能从这个节点往后开始出错。

从这里我们已经学会了两点:

  1. 使用 < meta charset = utf-8 > (或一些其他编码)是必不可少的 。
  2. 只有在 HTML 中指定的charset属性之前只能使用 ASCII 字符集。

最后,良好的html模版开始应该像下面一样。 像我们之前学过的文章一样,我们省略了headbody以及后面的标记。 这段代码做了两件正确的事情, 它定义了正确的文档类型, 并且设置了文档的字符集.

唯一剩下的问题是: 如果我忘记了这三个步骤之一,会发生什么? 好吧,第一和第三个步骤是最重要的。 传输实际上没有那么糟糕。 如果在HTTP的头部没有给定初始编码,浏览器将选择基于用户的区域设置的初始编码。 在德国的区域设置中,我们得到 Windows 1252。 这是实际是大多数国家的默认设置。 一些国家,如波兰和匈牙利,选择 Latin2,也被称为 iso 8859-2编码。

如果按照之前我们的练习去做,原则上我们不需要担心这个初始的编码. ASCII 是一个子集的 Unicode,大多数在使用的编码,实际上只是 ASCII 的扩展来满足一个或多个国家的具体需要。 在使用一个指定的字符集钱如果我们只使用基本的 ASCII 字符,应该没问任何问题。

大多数的错误是在像客户端发送数据,存储/读取或生成 meta 标签的语句时发生冲突. 如果出了错我们可能会看到类似于下面的效果图。 这不是一个令人愉快的用户体验。

Encoding ProblemEncoding ProblemEncoding Problem

还是重新选择正确的编码,这就是为什么 UTF-8 是最好的选择的原因。 加上其它编码足够我们显示的需要了. 然而,如果我们提供表单输入的字段,我们可能会有麻烦。 在这一点上我们不控制任何更多地使用的字符。 允许用户输入任何内容在这里。 让我们看看我们如何能控制表单输入的编码。

提交表单

如果表单提交一些确定的编码类型,和服务器响应的类型不一致,例如 GZip 编码类型相同。 表单的编码类型决定表单发送到服务器之前的序列化。 这种方法与HTTP verb结合在一起非常有用.

原始表单提交使用 POST 作为 HTTP 方法,但是 GETPUTDELETE也很常见。 并且只有POSTPUT方法支持body内容传输请求. 浏览器根据<form>元素的 enctype属性来指定的编码类型来构建内容. 通过在 HTTP 请求中设置的Content-Type-header来传输编码类型。

有三个既定的编码类型:

  1. URL 编码 (默认值,显式 application/x-www-form-urlencoded)
  2. 纯文本编码类型 (text/plain)
  3. 混合编码类型(multipart/form-data)

第一种和第二种是很相似的但他们还是有细微 (并且非常重要的) 差异。 第三个种方法是最强大的方法。 它甚至允许运送任意文件作为附件。

前两种类型之间的关键区别是,URL编码形式对表单所有名称和值进行百分比编码,而纯文编码传输做不到。 百分比编码保证接收方可以区分名称和值。 这种提交方式是纯文本表单提交做不到的. 第三个不一样的地方是构建每个实例时使用了边界字符串分割每个实例.

让我们通过提交一个简单表单看看差异在哪里。 表单包含下列代码:

提交表单,而无需指定任何编码类型传输下列内容:

URL编码将空格转换为加号。 原来的加号,像所有的"特殊"字符,按百分比编码规则转换。 这尤其适用于换行,原来的 \r\n,现在显示为 %0D%0A

让我们看看纯文本编码输出后看起来像的样子。

用换行来分割的一对对文本. 如果遇到内容中包含多行,可能会导致不正确的描述。

混合编码的优点是结合了纯文本提交的方式并且定义了分割字符串,基本上解决了纯文本编码的问题。 唯一的缺点是增加内容长度。

最后两个表单编码方法对我们输入的特殊字符不做任何转换。 表单传输方法主要靠相应的 <form>元素 charset 属性的设置。 如果没有这样的属性,使用页面的编码设置。 再次强调,设置了正确的编码是重要的。

将来我们将会看到第四个编码类型,称为application/json。 顾名思义,它会将表单内容打包为一个JSON字符串。

结论

选择正确的编码,可以简单只选取UTF-8。 使用相同的编码类型可以避免大部分的错误. 在运输过程中的定义编码是非常有用的,虽然在HTML中带有charset属性的<meta>元素不是必须要求的,但是这却是一种确定编码方式非常好的方法。

表单提交是一个过程,依赖于选择正确的编码 — — 不仅为文本,提交编码本身。 在一般情况下我们可以总是选择multipart/form-data作为 enctype,即使默认的编码类型可能更好 (较小) 的情况下。 在生产环境中我们永远不应该使用text/plain

参考资料

关注我们的公众号
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.