做站点运营时,大多數人盯的是标题、正文、内鏈和图片,這些确實重要。但蜘蛛第一次接触一個地址时,最先讀到的並不是 HTML 源碼,而是服務器返回的那几行响應头。头部信息寫错,後面的内容再規整,也可能被讀成乱碼、空白頁,或者被誤当成另一類资源。
响應头平时不顯眼,出問题时却很难從頁面表面看出来:浏览器可能照样正常顯示,只有換一個客戶端、換一種請求方式,問题才暴露出来。所以它更适合放進固定的巡检清單,而不是等出了異常再回头找。
蜘蛛看到的第一层信息
一次請求的流程大致是:解析域名、建立连接、服務器返回狀態碼和响應头、再返回正文。蜘蛛判断這個地址是什么類型的内容、用什么编碼解析、要不要繼續抓,很大一部分依據就来自响應头,而不是正文里的 meta 标簽。
当两者说法不一致时,服務器返回的头部通常優先級更高。這也是為什么有些頁面在源碼里明明寫了字符集声明,抓取端讀出来依然是乱碼——头部先给出了另一個答案。
几類容易寫错的响應头
Content-Type 與字符集
常见的寫法是 Content-Type: text/html; charset=utf-8。問题往往出在两個地方:一是類型寫错,把 HTML 頁面标成 text/plain、application/json,甚至 application/octet-stream,蜘蛛可能直接按普通文本或下载资源處理;二是只寫了 text/html,漏掉字符集,解析端只能靠猜,遇到中文就容易出現乱碼。
還有一種情况是模板或框架預設輸出 ISO-8859-1,而頁面實际是 UTF-8,正文里的中文會整段變成問号或方块。這類問题在浏览器里可能被自動纠正,抓取端却未必有這么宽容。
Content-Encoding 與压缩声明
開啟 gzip 或 brotli 压缩本身是好事,能减少传輸体积。但如果声明與實际不符,比如头部说 gzip 而返回的是未压缩内容,或者压缩层級嵌套错誤,接收方解出来就是一段乱碼。改過 Nginx、CDN 压缩配置之後,最好顺手驗證一下头部和内容是否對得上。
X-Robots-Tag
這個头部可以针對單個地址、整個目錄甚至某類文件設定抓取和索引規則,作用范围比頁面里的 meta 标簽更广,而且不依赖 HTML 能否被解析。它的問题在于太隐蔽:一個批量下發的 noindex,可能让整批 PDF、图片或接口頁悄悄登出。
排查时要留意的是,它可能来自服務器配置,也可能来自 CDN 或安全防護层的預設策略,几處叠加之後效果會被放大。
Vary 與缓存相關字段
如果站点對移動端和桌面端返回不同内容,Vary 字段會影响缓存按哪個维度区分版本。配置不当,可能出現同一個地址在不同邊缘节点返回不同頁面、甚至返回對方版本的情况。這類問题不一定會立刻顯現,但會让抓取结果變得不稳定。
一套简單的自查步骤
- 挑几個有代表性的地址:首頁、栏目頁、詳情頁、列表頁、图片或附件頁各取一两個。
- 用命令行工具只取头部,例如 curl -I 加上地址,观察狀態碼和這几行關键字段。
- 带上不同 User-Agent 再請求一次,對比返回的头部和正文是否一致,重点看是否被差异化處理。
- 在浏览器開發者工具的網絡面板里對照头部與頁面實际渲染结果,確認字符集和内容類型對得上。
- 對图片、PDF、接口返回等非 HTML 资源單獨抽查,它們最容易被類型声明誤伤。
- 把發現的異常记錄成清單,标明是服務器配置、框架預設值還是 CDN 策略造成的,避免改完又反彈。
容易被忽略的几個细节
- 狀態碼是 200,但正文長度為 0 或极短,头部看起来一切正常,實际是空壳頁面。
- 測試环境和线上环境用了同一套模板,头部規則跟着一起上线。
- 更換 CDN 或調整安全策略後,头部字段被中間层改寫,源站配置其實没變。
- 只检查了 HTML,忽略了站点地图、RSS、接口文件這些同样需要正确類型的地址。
- 批量規則寫得太宽,例如對整站目錄统一加限制,誤伤了正常内容。
响應头這類問题,特点是不痛不痒地待着:頁面能打開,用戶看不出差別,只有抓取和解析环节會受影响。所以它更适合定期抽查,而不是等資料明顯下滑再回头排查。
小结
把响應头纳入常規巡检,成本並不高:几條命令、几次對比,就能排除掉一批隐蔽問题。重点看 Content-Type 和字符集是否與頁面實际编碼一致、压缩声明是否属實、X-Robots-Tag 有没有被批量誤设、缓存相關字段是否让同一個地址给出多套结果。發現問题後回到配置源头修改,比在頁面上打补丁更稳妥。