...
Back

你放出去的每个主机名,都会被爬

单域名还是加一个 app 子域名,通常按 Cookie、部署和 CORS 来争。搜索另有一笔账:你暴露的每个主机名和协议都会被抓取、被报告,每一个都需要一份策略。

你放出去的每个主机名,都会被爬

你放出去的每个主机名,都会被爬

r/webdev 本周有个帖子,标题本身就是全部的问题:Everything on XYZ.com or XYZ.com+app.XYZ.com。所有东西都放在一个域名上,还是拆成主域名加一个 app. 子域名?

这道题通常沿着三条线来争,而且三条都是真问题。Cookie:应用放到单独的主机上,会话 Cookie 就只属于应用,不会和营销页面、以及页面上那些第三方脚本搅在一起。部署:两个主机可以按两套节奏各自发布。CORS:一旦拆开,原本同源的一部分请求就变成了跨源,预检和凭据规则都得重新弄对。

搜索很少出现在这张清单上,可它会单独寄来一张账单。你暴露出去的每一个主机名、每一种协议,不管本意是不是公开,都会被发现、被抓取、被写进报告。每一个都需要自己的答案:跳不跳转,规范网址指向哪里,robots 怎么写,根路径返回什么。我们的立场是:主机要有意识地拆,而且要赶在爬虫来问之前,给每个主机定好策略。


搜索在我们站上看到了什么

我们的规范主机是主域名 metasignaltech.com。www 永久跳转到主域名,http 跳转到 https,而 / 会根据浏览器的 Accept-Language 请求头,跳到 /en 这样的语言前缀。应用下载从 download.metasignaltech.com 发,视频(HLS 播放列表和分片)从 video.metasignaltech.com 发,两者都直接出自对象存储。这样,大文件既不经过应用的源站,也不占应用的缓存。按常规的那几条标准衡量,这样拆没有错。

我们在 Search Console 里用的是网域资源(Domain property),它覆盖所有子域名和两种协议,所以同一份报告里混着上面所有主机。网页索引报告(数据截至 2026-09-21)显示:已编入索引 177 个网页,未编入索引 204 个。未编入的原因里,有三类值得逐行看。

网页会自动重定向(Page with redirect):23 个网址。 包括 www.metasignaltech.com/、http://www.metasignaltech.com/、http://metasignaltech.com/、主域名的根路径 /、带尾斜杠的语言根路径(比如 /ja/),还有 www 和主域名上各一条带着 ?from=AppAgg.com&utm_campaign=AppAgg.com&utm_medium=referral&utm_source=AppAgg.com 的根网址,来自某个应用目录网站上的链接。这些全在预期之内。这一类其实是好消息:它说明 Google 正顺着我们设计好的跳转在走。

未找到(404):20 个网址。 其中一个是 https://download.metasignaltech.com/,也就是下载主机的根。这个主机只在特定路径上提供文件,/ 上什么都没有。另外几个是 /mo、/mois、/月 和 /mês,是 Google 从价格单位字符串里抽出来的:/mo 这样的字符串单独出现在我们页面的源码里,就被拿去当成了网址。我们已经不再输出以斜杠开头的单位字符串。

已抓取 - 尚未编入索引(Crawled – currently not indexed):8 个网址。 包括视频主机上的一个 HLS 播放列表(…/hls/720p.m3u8)、下载主机上的一个旧 APK、/_next/static/media/ 下的一个字体文件,以及一些旧的 www 网址。

这些都算不上事故。但每一行都是一个没人有意回答过的问题。我们拆出那两个主机,考虑的是源站和缓存,跟搜索毫无关系;报告却替我们问了出来:下载主机在 / 上该说什么?播放列表到底该不该被抓?


每个主机一份策略

有不止一个主机的站点,都应该能把下面这张表填出来。app. 那一行对应的就是标题里那种拆法;两类文件主机的几行,是给任何只发字节的主机的建议。

主机/ 返回什么跳转索引控制站点地图
规范主机(主域名)一个页面,或一跳到达页面只用于规范化规范网址指向自身收,且只收这个主机
www永久跳转到主域名所有路径跳转本身就是答案不收
http://永久跳转到 https所有路径跳转本身就是答案不收
app.(如果拆)登录页或控制台仅根路径登录后的页面加 noindex不收
下载主机跳到下载页,或一个有意为之的 404仅根路径自己的 robots.txt;文件带 X-Robots-Tag: noindex不收
媒体主机同下载主机仅根路径自己的 robots.txt,禁止抓取播放列表和分片不收

表背后有三条规则,都很容易弄错。

robots.txt 按主机、按协议各算各的。 主域名上的那份文件,管不到 download. 和 video.。一个主机如果没有自己的 robots.txt,默认就是整站可抓。

被屏蔽的网址,亮不出自己的答案。 被 robots.txt 挡在门外的爬虫,根本不会去取那个网址,也就永远看不到上面的跳转或 noindex 响应头。所以绝不要屏蔽 www 或 http。对文件,每条路径只选一种工具:noindex 响应头能把文件从搜索结果里拿掉,代价是一次抓取;Disallow 省下这次抓取,对体积大的媒体分片,这一点很实际,但只要有人链接了这个网址,它仍可能以没有内容的形式出现在结果里。

每个主机都有根路径,总会有东西来请求它。 在那里返回 404 没问题,前提是这是一个决定,而不是一个疏忽。跳到列出这些文件的页面则更友好,照顾到那个把网址截短、想看看这里还有什么的人。


定一次,写下来,测起来

只存在于某个人脑子里的策略,活不过下一次迁移。把这张表放进仓库,放在路由配置旁边,再把每一行变成每次部署都会跑的检查:

# 非规范入口:一次永久跳转,直达规范网址
for u in http://example.com/ http://www.example.com/ https://www.example.com/pricing; do
  curl -s -o /dev/null -w "%{http_code} $u -> %{redirect_url}\n" "$u"
done
 
# 文件主机:根路径返回什么,文件有没有带 noindex
curl -sI https://download.example.com/ | head -1
curl -sI https://download.example.com/app-1.2.0.zip | grep -i x-robots-tag
 
# 规范主机:站点地图里的每个网址都是 200,且规范网址指向自己
curl -s https://example.com/sitemap.xml | grep -o '<loc>[^<]*' | cut -c6- |
while read -r u; do
  code=$(curl -s -o /tmp/page -w '%{http_code}' "$u")
  canon=$(grep -o 'rel="canonical" href="[^"]*"' /tmp/page | cut -d'"' -f4)
  [ "$code" = 200 ] && [ "$canon" = "$u" ] || echo "BAD $code $u -> $canon"
done

经过这个月的修复,我们的站点地图列了 87 个网址,全部在规范主机上,每个都返回 200,规范网址都指向自身。而索引报告在所有主机上一共统计了 381 个网址(177 + 204)。站点地图是你告诉搜索"我指的是哪些网址"的地方;报告则是你发现它另外还找到了哪些的地方。

如果混在一起的报告不好读,可以给每个主机再加一个网址前缀资源(URL-prefix property)。网域视图也要留着:只有它会把你已经忘掉的主机列出来。


检查清单

  • 列出所有会响应的主机名和协议,包括 www 和 http,并定下唯一的规范主机。其余主机要么跳转到它,要么只发文件。
  • 每个主机都写清楚:/ 返回什么,哪些要跳转,索引怎么控制,进不进站点地图。
  • 每个文件主机都要有自己的 robots.txt;文件的索引用 X-Robots-Tag 控制,因为文件里没有 HTML 可以放 meta 标签。
  • 页面源码里不要出现以 / 开头、却又不是路由的字符串。
  • 每次部署都重跑这些检查。

一个域名还是两个,用 Cookie 和 CORS 来争完全没问题。只是答案里要把主机数清楚,因为搜索一定会数。