HTTP标头应使用哪种字符编码?


122

我正在为HTTP标头使用“有趣的” HTML特殊字符(✰)(有关更多信息,请参见http://html5boilerplate.com/),Server并且想知道是否按照规范“允许”使用它。

  • 在Windows Xp Pro SP 3的Chrome浏览器的开发工具中使用“网络”选项卡,我看到✰很好。

  • 在IE8中,✰ 不能正确显示。

  • w3.org HTML验证程序无法正确呈现(â°而是显示“ ”)。

现在,我不太热衷于字符编码……坦率地说,我并不太在乎它们。我只是盲目地使用被告知的UTF-8 cus。:-)


差异是由不同的解析器/浏览器/引擎/(无论它们被称为)中的错误引起的吗?

是否有此规范,或者是否有HTTP标头“值”的允许字符列表?


29
通常最好问这个问题:“ http标头值中允许使用哪些字符”
Akrikos 2012年


2
“现在,我不太喜欢字符编码……坦率地说,我并不太在乎它们;我只是盲目地使用被告知的UTF-8 cus。:-)” -必须链接到 joelonsoftware.com/2003/10/08/…–
d4nyll

Answers:


124

简而言之:仅保证ASCII起作用。为了向后兼容,允许使用某些非ASCII字节,但不应显示这些字节。

HTTPbis放弃了,并指定在标头中除了ASCII外没有有用的编码:

从历史上看,HTTP允许使用ISO-8859-1字符集[ISO-8859-1]中的文本显示字段内容,仅通过使用[RFC2047]编码来支持其他字符集。实际上,大多数HTTP标头字段值仅使用US-ASCII字符集[USASCII]的子集。新定义的标头字段应将其字段值限制为US-ASCII八位位组。接收者应该将字段内容(obs-text)中的其他八位字节视为不透明数据。


以前,1999年的RFC 2616对此进行了定义:

仅当根据RFC 2047 [14]的规则进行编码时,* TEXT的单词才能包含ISO-8859-1 [22]以外的字符集中的字符。

RFC 2047是MIME编码,因此它是:

=?UTF-8?Q?=E2=9C=B0?=

但我认为没有太多(如果有的话)客户支持它。


7
那么,这是什么意思呢?“✰”有效/允许吗?
大卫·默多克

8
再说一个非常有用的答案:“ UTF-8”是字符集,“ Q”表示该值将是“ quoted-printable”。如果要对值进行BASE64编码,也可以使用“ B”。
GargantuChet 2014年

1
@porneL,那么“不透明数据”是什么意思?什么究竟应该在HTTP接收者,当它接收到这些“不透明数据”?
Pacerier 2014年

1
@Pacerier“不透明数据”表示这是一个带有一堆字节的黑匣子,应用程序不应尝试显示或解释这些字节(例如二进制数据)。它所发生的情况取决于标题,范围可能从“无”到“丢弃”。
Kornel 2014年

@Kornel,顺便说一句,为什么您将用户名更改为kornel?
Pacerier '16

10

请先阅读评论,此答案可能会从正确的来源得出错误的结论,需要进行编辑。


您可以使用任何可打印的ASCII字符,并且不能使用诸如✰(不是ASCII)的特殊字符。

提示:您可以使用JSON进行编码。

编辑:起初可能并不明显,标头中定义的字符编码仅适用于响应正文,不适用于标头本身。(因为这会导致鸡和蛋的问题。)


我想根据Penchant链接的规范总结所有相关定义。

message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )

因此,我们追求field-value

LWS            = [CRLF] 1*( SP | HT )
CRLF           = CR LF
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>

LWS代表线性空白。本质上,LWS是空格或制表符,但是您可以通过在空格或制表符之前开始新行来将字段值分成多行。

让我们简化为:

field-value    = <any field-content or Space or Tab>

现在我们关注领域内容

field-content  = <the OCTETs making up the field-value
                 and consisting of either *TEXT or combinations
                 of token, separators, and quoted-string>
OCTET          = <any 8-bit sequence of data>
TEXT           = <any OCTET except CTLs,
                 but including LWS>
CTL            = <any US-ASCII control character
                 (octets 0 - 31) and DEL (127)>
token          = 1*<any CHAR except CTLs or separators>
separators     = "(" | ")" | "<" | ">" | "@"
                 | "," | ";" | ":" | "\" | <">
                 | "/" | "[" | "]" | "?" | "="
                 | "{" | "}" | SP | HT

TEXT是最通用的,包括所有其余部分,因此请忽略其余部分。 这是US-ASCII字符集(= ASCII)

如您所见,允许所有可打印的ASCII字符。


3
您引用的段落相矛盾。为什么说“没有像✰这样的特殊字符”?特殊字符只是OCTETs和由于TEXT任何OCTET0 - 31,这意味着所有OCTET从s 32255 被允许。✰的八位组226156以及176和他们的三个被允许根据你引用的段落,因此✰是允许的。
Pacerier,2014年

2
@Pacerier您似乎完全正确,我不明白为什么我得出了我的结论。
zupa 2014年

@Pacerier,但我还没有准备好对其进行编辑,因为我需要再次仔细检查规格。恐怕其他细节仅限于US-ASCII字符集,这反过来将支持该结论,但仍会导致推理不足。
zupa 2014年

1
说“您可以用JSON编码任何东西”有点误导。JSON允许使用Unicode字符,而HTTP标头应为US-ASCII。Unicode字符将被视为“不透明”数据,因此HTTP规范未定义其行为。话虽这么说,通过\ uXXXX转义序列转义Unicode字符,可以使JSON安全地包含在HTTP标头中。
2014年

@zupa,另一个问题是...“ 除了CTLs ”是什么意思?这是否意味着字符CRLF被允许?还是意味着允许连续序列“ CR LF SP/ HT”?(换言之,可首部值包含单个CRLFHT制罐标头值包含字符?CRLFHT以任何顺序和量?)
Pacerier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.