Content-Language 说明正文是哪种语言,不是「客户端想要哪种」。
它是描述,不是协商结果本身。
上一节讲正文被怎么压,这一节讲正文用哪种语言写。它和 6.4.4 的 Accept-Language 正好一问一答。
一、它说的是「实际是什么」
Accept-Language: en 是客户端的愿望;Content-Language: en 是服务端交出的答案。
两个方向,别搞反。
Demo 里五组请求:要 en 给 en(32 字节),要 ja 给 ja(54 字节),要 zh 给 zh(27 字节);
要 fr 服务端没有,退到默认的中文;干脆不发,也退到中文。
五组的 Content-Language 都如实反映了正文的实际语言——包括那两组「客户端要的不是这个」的情况。
这就是「描述」的含义:说真话,而不是说对方爱听的。
二、为什么中文字节数最多还是最少
有意思的是那三个字节数:en 32、ja 54、zh 27。
中文句子短、日文假名多、英文单词长,加上 UTF-8 里汉字占三字节、假名也占三字节,结果就是这样。
这提醒一件事:Content-Language 的长度和「内容多少」无关。
它只说语言,不描述体量——体量是 Content-Length 的事。
另外别拿字节数反推语言。
判断语言要靠这个首部,靠字节猜是猜不准的(UTF-8 里 ASCII 和汉字的比例随时会变)。
三、它可以写多个
Content-Language: zh-CN, en 表示正文里两种语言都有。产品说明书、双语公告就是这样。
值用的是语言标签(BCP 47):zh、zh-CN、en-US、ja。主标签必填,子标签可选,用连字符分隔。
写错标签不会报错,但会让缓存和搜索引擎判错。zh_CN(下划线)是错的,必须是 zh-CN。
四、动手 Demo:五组 Accept-Language,看 Content-Language 怎么答
服务端准备中文、英文、日文三个版本,按客户端点的语言挑一个, 并在响应里如实写出正文实际用的是哪种语言。
docs = {u'zh': ZH_BYTES, u'en': EN_BYTES, u'ja': JA_BYTES}
def fn(raw, st):
want = hd.get(u'accept-language', u'')
pick = u'zh' # 默认语言
for tag in (u'en', u'ja', u'zh'):
if tag in want:
pick = tag
break
return X.reply(u'HTTP/1.1 200 OK',
[(u'Content-Language', pick)], docs[pick])
实跑输出:
--------------------------------------------------------------------
Content-Language:正文是哪国话
--------------------------------------------------------------------
Accept-Language Content-Language 字节 正文开头
en en 32 This p
ja ja 54 このページは
zh zh 27 这一页是中文
fr zh 27 这一页是中文
(不发) zh 27 这一页是中文
最后两行是重点:要法语(服务端没有)和干脆不发,都退到默认的中文版本。
所以 Content-Language 的作用不是「告诉客户端该用哪种语言」,
而是「告诉客户端这份正文究竟是哪种语言」——它是描述,不是协商结果本身。
这点和 Accept-Language 正好一对:一个问,一个答。
另外 Content-Language 允许写多个,比如 `zh-CN, en`,表示正文里两种语言都有。
前三条要什么给什么,Content-Language 与请求对得上:en 32 字节、ja 54 字节、zh 27 字节。
第四条要法语,服务端没有,退到中文,但 Content-Language 老实写 zh。
第五条干脆不发 Accept-Language,结果一样。
这两行是整个 Demo 的重点:客户端要什么,和正文是什么,是两件事。
服务端不撒谎,客户端才能正确决定要不要自己翻译。
三个字节数的差也不是「内容多少」,只是句子长短加编码宽度的结果。
30 秒实验
- 把
Accept-Language写成fr, zh;q=0.1,看服务端会不会挑到中文。 - 给响应加
Content-Language: zh-CN,看字节数变化。 - 想一想:如果正文里中英文混排,这个首部该怎么写?
常见误区
- 「Content-Language 表示客户端想要的语言」——那是 Accept-Language。
- 「没有对应语言就该报错」——通常退到默认版本。
- 「
zh_CN和zh-CN一样」——语言标签必须用连字符。
自测三问(点开对答案)
1. `Content-Language` 和 `Accept-Language` 的关系是什么? —— 一个问、一个答;前者描述实际语言,后者表达偏好。 2. 客户端要法语但服务端只有中文,响应该怎么写? —— 给中文版本,`Content-Language: zh` 如实写,不撒谎。 3. 语言标签能不能用下划线? —— 不能,必须用连字符,比如 `zh-CN`。语言是「内容层面的描述」。接下来这个字段是实体首部里最硬的一个:Content-Length。
- ☐ (本节完,下一节 6.6.4 Content-Length)