Content-Transfer-Encoding 是 HTTP 标头吗?

Posted

技术标签:

【中文标题】Content-Transfer-Encoding 是 HTTP 标头吗?【英文标题】:Is Content-Transfer-Encoding an HTTP header? 【发布时间】:2011-11-09 06:23:25 【问题描述】:

我正在编写一个返回 base64 编码的 PDF 文件的 Web 服务,所以我的计划是在响应中添加两个标头:

Content-Type: application/pdf
Content-Transfer-Encoding: base64

我的问题是:Content-Transfer-Encoding 是一个有效的 HTTP 标头吗?我认为它可能只适用于 MIME。如果不是,我应该如何制作我的 HTTP 响应来表示我正在返回一个 base64 编码的 PDF 的事实?谢谢。

编辑:

看起来 HTTP 不支持此标头。来自RFC2616 Section 14:

注意:虽然 Content-MD5 的定义与 HTTP 完全相同 就像在 RFC 1864 中的 MIME 实体一样,有几种方法可以 Content-MD5 对 HTTP 实体的应用不同于它的 应用于 MIME 实体。一是 HTTP 与 MIME 不同,它确实 不使用 Content-Transfer-Encoding,并使用 Transfer-Encoding 和 内容编码。

关于我应该将标题设置为什么的任何想法?谢谢。

编辑 2

在这个 php 参考手册页的 cmets 中找到的许多代码示例似乎表明它实际上 一个有效的 HTTP 标头:

http://php.net/manual/en/function.header.php

【问题讨论】:

为什么还要base64编码? 我不知道,我刚刚得到了这个项目。它目前正在生产中,因此这是消费者期望它的行为方式。 嗯,它不是HTTP头字段,UA忽略它,base64编码真的没用; HTTP 允许二进制传输。 base64 编码没有意义; HTTP 允许二进制负载,因此 HTTP 中不存在 Content-Transfer-Encoding。 @Potaswatter:Web 浏览器几十年来一直没有遇到二进制数据问题,否则它们不会显示 GIF 和 JPG。 【参考方案1】:

根据RFC 1341(由RFC 2045 废弃):

Content-Transfer-Encoding 头域,可用于 指定应用于数据的辅助编码,以便 允许它通过可能具有的邮件传输机制 数据或字符集限制。

及以后:

许多可以通过电子邮件有效传输的内容类型 以其“自然”格式表示为 8 位字符或 二进制数据。此类数据无法通过某种传输方式传输 协议。例如,RFC 821 将邮件消息限制为 7 位 具有 1000 个字符行的 US-ASCII 数据。

因此,有必要定义一个标准机制 将此类数据重新编码为 7 位短线格式。 (...) 这 Content-Transfer-Encoding 字段用于指示类型 用于表示身体的变换 以可接受的运输方式。

由于您有一个与电子邮件毫无共同之处的网络服务,因此您不应使用此标头。

您可以使用Content-Encoding 标头表示传输的数据已被压缩(gzip 值)。

我认为在你的情况下

Content-Type: application/pdf

就够了。此外,您可以设置Content-Length 标头,但在我看来,如果您正在构建Web 服务(它不是http 服务器/代理服务器)Content-Type 就足够了。请记住,如果使用不当,某些特定的标头(例如Transfer-Encoding)可能会导致意外的通信问题,因此如果您不能 100% 确定某些标头的使用 - 如果您真的需要它 - 请不要不要使用它。

【讨论】:

我正在设置 Content-Length 标头。不添加任何东西可能更安全……网络服务按原样工作正常。 该标头似乎在 SOAP over HTTP 中被大量使用 en.wikipedia.org/wiki/MIME#Content-Transfer-Encoding "MIME 标准定义的内容类型在电子邮件之外也很重要,例如在 HTTP for the World 等通信协议中万维网。HTTP 要求在类似电子邮件的消息的上下文中传输数据,尽管数据通常不是真正的电子邮件。” Piotrek:“当然,您可以随时在线发送自己的标头 - 所有以 X 开头的(例如 X-Anything)都完全符合 RFC。” - 不,它们不是。 Piotrek:“x-”前缀在 HTTP 中从来就不是特别的。 请注意,X- 标头的折旧现在是 RFC tools.ietf.org/html/rfc6648【参考方案2】:

rfc2616 第 14.15 节中的注释是明确的:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

"注意:虽然 Content-MD5 的定义与 HTTP 在 RFC 1864 中用于 MIME 实体,有几种方法 其中 Content-MD5 对 HTTP 实体的应用 不同于它对 MIME 实体的应用。 一个是 HTTP 与 MIME 不同,它不使用 Content-Transfer-Encoding,并且 确实使用传输编码和内容编码。另一个是 HTTP 比 MIME 更频繁地使用二进制内容类型,所以它是 值得注意的是,在这种情况下,用于计算的字节顺序 摘要是为该类型定义的传输字节顺序。 最后,HTTP 允许传输具有多种文本类型中的任何一种 换行约定,而不仅仅是使用 CRLF 的规范形式。”

【讨论】:

【参考方案3】:

正如之前和here 所回答的那样,有效的Content-Transfer-Encoding HTTP 响应标头不存在。此外,已知的标头 Content-EncodingTransfer-Encoding 没有合适的值来表达 Base64 编码的响应正文。

从这里开始,没有客户端会期望声明为 application/pdf 的响应被编码为 Base64!如果您想这样做,最好使用不同的内容类型,例如:

Content-Type: application/pdf+base64

在这种情况下,客户端会知道一些 Base64 编码的数据即将到来(基本子类型是加号后面的后缀)并提示其中有 PDF。

即使这有点 hacky(+base64 不是 official media type suffix),但至少会以某种方式满足某些标准。最好使用自定义内容类型而不是滥用标准 HTTP 标头!

当然,无论如何,没有浏览器能够直接打开这样的响应。也许您的项目应该考虑创建另一个提供二进制 PDF 响应的端点并将其标记为已弃用。

【讨论】:

以上是关于Content-Transfer-Encoding 是 HTTP 标头吗?的主要内容,如果未能解决你的问题,请参考以下文章

解码 8bit 邮件消息:Content-Transfer-Encoding: 8bit

Content-Transfer-Encoding 是 HTTP 标头吗?

如何在 Python 中更改我的 Content-Transfer-Encoding 标头?

发送包含长 http-link 的 PHP mail() 时应该使用啥 Content-Transfer-Encoding?

检查电子邮件标头注入

读取邮件