📘 第六章 HTTP首部
📄 一句话概括

From 的本意是让客户端留下联系邮箱,方便服务端找上门。 没有任何强制力,所以它实际上已经死了。

📝 本节和前面几节的关系

上一节的字段很实用,这一节是个反例:设计得再好,没人用也是空的。

一、设计意图

它的目标用户是爬虫和自动化程序:抓取方主动填一个邮箱,站长觉得抓得太狠时能联系上人。 这个想法本身是善意的,也符合早年互联网「先沟通再封禁」的风气。 但它有个致命缺陷:全凭自愿。不填没有惩罚,填了也没有好处。

二、为什么它失效了

三方都没动力。爬虫作者不想暴露身份(尤其是恶意的那些);站长也不看这个字段(因为不可信); 浏览器更不会替用户填邮箱——那是隐私。 Demo 里三组请求:不带、带合法邮箱、带一个 not-an-email 的垃圾值。 服务端一个都没校验,因为没人会去校验一个没人用的字段。 今天要留联系方式, 业界的做法是在 User-Agent 里写上项目地址(比如 MyCrawler/1.0 (+https://example.com/bot)), 或者提供 /robots.txt 里约定的说明页。

三、从它身上能学到什么

HTTP 里有不少这样的字段:设计合理,但缺了强制力或者缺了实际收益,最后变成规范里的死条文。 对比一下 Referer:它也有隐私问题,但因为有实际收益(防盗链、来源统计),所以活到了今天, 还发展出了 Referrer-Policy。 所以判断一个字段会不会活下来,看两件事:有没有人从中获益,有没有人被迫遵守。 两样都没有的,就会变成 From。

四、动手 Demo:三种取值,服务端一律不校验

分别不带 From、带一个合法邮箱、带一个明显不合法的字符串,看服务端读到什么、会不会拒绝。

def responder(raw, st):
    first, hd, _b = H.parse_headers(raw)
    st[u'from'] = hd.get(u'from', u'')
    return reply(u'HTTP/1.1 200 OK',
                 [(u'Content-Type', u'text/plain; charset=utf-8')],
                 (u'From: ' + (st[u'from'] or u'(没发)')).encode(u'utf-8'))

实跑输出:

--------------------------------------------------------------------
From:一个几乎没人用的字段
--------------------------------------------------------------------
  【不带 From】
    服务端读到               (空)
    有没有校验               没有——这个字段没人检查

  【带邮箱】
    服务端读到               [email protected]
    有没有校验               没有——这个字段没人检查

  【带一个不合法的值】
    服务端读到               not-an-email
    有没有校验               没有——这个字段没人检查

  它的本意是「让服务端能联系到发请求的人」,用在爬虫上:
  抓取方主动留下联系方式,方便站长找上门。
  但没有任何强制力,所以爬虫基本不填,填了也没人看。
  今天要留联系方式,业界的做法是在 `User-Agent` 里带上项目地址,
  或者干脆用 robots.txt 约定。`From` 这个字段实际上已经死了。

不带:服务端读到空,回 200。 带 [email protected]:服务端原样读到,回 200。 带 not-an-email:服务端照样原样读到,照样回 200。三组的「有没有校验」那一行都是「没有」。 这就是它的现状:能传,但传什么都行,所以传了也没意义。

30 秒实验

  1. 给服务端加一个「From 不是合法邮箱就回 400」的校验,想想会不会误伤。
  2. 把 From 换成 User-Agent 里带联系方式,对比两种做法的效果。
  3. 想一想:还有哪些 HTTP 字段是你见过但从来没用的?

常见误区

  1. 「From 是必填的」——完全可选,而且没人检查。
  2. 「From 能防止被封」——没有强制力,填了也不代表什么。
  3. 「From 是响应首部」——它是请求首部,只有客户端会发。
自测三问(点开对答案) 1. `From` 的设计意图是什么? —— 让客户端留下联系邮箱,方便服务端在抓取过频时联系。 2. 它为什么失效了? —— 全靠自愿,不填没惩罚、填了没好处,三方都没动力。 3. 今天要留联系方式该怎么做? —— 写在 `User-Agent` 里带上项目地址,或者提供 robots.txt 说明页。

说完了这个死字段,下一个是每个请求都必须有的那个。

相关笔记