跳到正文
LinkProfit

移动应用与 deep link

从短链接打开你的应用,没装应用就送去应用商店,在你自己的域名上托管关联文件,并在安装完成后读取点击上下文。

更新于 2026年8月14日

一条通往移动应用的短链接,同时面对三类人:已经装了应用的人、没装的人,以及浏览器活在另一个应用里的人。本页把这三类都讲清楚,另外还有两处真正决定成败的配置——你域名上的关联文件,以及你的应用在首次启动时可以读取的、延迟送达的点击上下文。

移动端这一节能做什么

打开一条链接,切到移动端标签页并启用移动端目标地址。每个平台都可以填写三个地址:

  • 应用链接 —— 应用内部的地址:你自己的 scheme 加路径(myapp://product/42)、一个 Android intent,或者一条通用的 https 链接。
  • 应用商店地址 —— App Store 或 Google Play 页面,在应用没能打开时使用。
  • 网页兜底地址 —— 给那些你宁可根本不送去应用商店的访客准备的页面。

这些都不是必填的。只填了应用商店地址的链接,就是一次普通的商店跳转。应用链接和应用商店地址都填了的链接,才会得到完整的行为:页面先尝试打开应用,什么都没发生时再转去商店。

另外两个设置决定在普通手机浏览器之外会发生什么:

  • 平板 —— 按手机处理(默认),还是按桌面端处理。
  • 应用内浏览器 —— 链接在 Instagram、TikTok、Facebook 或类似应用内部打开时该怎么办。

桌面端访客如果你设置了桌面端目标地址就去那里,否则就去链接的主目标地址。除非你明确要求,移动端这一节不会改变桌面端访客看到的任何东西。

应用内浏览器为什么需要单独一条规则

社交信息流里的大多数链接点击,根本到不了 Safari 或 Chrome。它们在应用自身的 web view 里打开,而其中好几种 web view 会把每一次导航都攥在自己手里:通用链接留在 web view 内,自定义 scheme 则悄无声息地什么也不做。这不是你能从链接这一侧修好的缺陷——它是拥有那个 web view 的应用做出的决定。

所以这个设置给你三个诚实的选项:

| 选项 | 访客会得到什么 | | --- | --- | | 尝试打开应用 | 中转页会尝试应用链接;当已知这个 web view 会拦住它时,页面会跳过等待,直接说明如何在手机浏览器里重新打开该链接。 | | 直接前往应用商店 | 完全不尝试打开应用 —— 适合以商店页面为目标的拉新推广。 | | 前往网页兜底地址 | 访客留在网页上,对内容类链接来说,这往往是最好的答案。 |

关联文件:让链接静默打开应用的那处配置

要让一条链接不经过浏览器停顿就打开你的应用,操作系统必须知道你的域名和你的应用属于同一家。两个平台都通过域名自身提供的一个文件来确认这一点:

https://go.brand.com/.well-known/apple-app-site-association
https://go.brand.com/.well-known/assetlinks.json

这些文件不用你来写。在域名里打开该域名,在移动应用下添加你的应用:

  • iOS:形如 TEAMID.com.company.app 的应用 ID,以及应用应当接管的路径(* 覆盖所有短链接);
  • Android:包名,以及来自 Play Console 的 SHA-256 签名指纹。

平台会生成这两个文件并从你的域名提供,响应完全符合两个平台的要求:状态码 200、无跳转、application/json、传输层不压缩。最后这一条比听上去更要紧——在传输途中把文件 gzip 压缩的代理,是应用链接悄无声息失效最常见的原因之一。

检查配置

检查文件按钮会从你线上的域名取回这两个文件,并报告平台会看到什么。每一项检查结果都对应着具体的修复办法:

| 检查结果 | 该怎么做 | | --- | --- | | 域名没有响应 | 该域名还没有开始提供服务,或者 DNS 仍在传播。 | | 文件缺失 | 该域名下没有配置任何应用,或者请求根本没有到达平台。 | | 域名对该地址做了跳转 | 域名前面有什么东西改写了 /.well-known/。各平台在这里不会跟随跳转。 | | 返回的类型不对 | 响应是 HTML,通常是另一个服务返回的 404 页面。 | | 响应是压缩过的 | 有代理在压缩这个文件。两个平台的检查都可能因此失败。 | | 没有声明任何应用 | 文件本身有效,但对那个平台是空的 —— 请在控制台里添加应用。 |

文件就位之后,两个平台都会把它们缓存在自家的 CDN 上,因此一次全新安装可能要过一阵才能拿到改动。在测试期间,重装应用是强制它重新读取的可靠办法。

安装之后延迟送达的点击上下文

一位没装你应用的访客点了链接,落到应用商店,装好应用并打开它。在那一刻,应用对这个人从哪里来一无所知——浏览器会话和应用是两个互不相干的世界。

打开安装完成后再传递点击上下文,平台就会把一份很短的设备指纹保留大约两小时:平台、操作系统主版本号、语言、国家/地区、屏幕尺寸、时区和网络运营商。里面没有 IP 地址,没有广告标识符,也没有任何能追溯到具体某个人的东西。

首次启动时,你的应用向平台询问是否发生过一次点击:

curl -X POST https://go.brand.com/__dl/claim \
  -H 'content-type: application/json' \
  -d '{
    "platform": "ios",
    "os_version": "17.4",
    "language": "de",
    "timezone_offset": 120,
    "screen_width": 1170,
    "screen_height": 2532,
    "pixel_ratio": 3
  }'

匹配成功时,返回原始链接及其营销活动标记:

{
  "matched": true,
  "confidence": "high",
  "score": 100,
  "matched_on": ["screen", "timezone_offset", "language", "os_version"],
  "url": "myapp://product/42",
  "domain": "go.brand.com",
  "slug": "promo",
  "link_id": "lnk_...",
  "utm": { "utm_source": "newsletter" },
  "click_id": "...",
  "clicked_at": "2026-08-14T10:00:00.000Z"
}

没有匹配时返回 {"matched": false} —— 对同一次点击发起的第二次请求同样如此,因为这条记录只会被交付一次。

把限制直说清楚

  • 匹配是概率性的。 同一型号、同一网络、同一时区和语言的两台设备,在这套方法看来一模一样。正因如此,每个回答都带着一个 confidence 和用来判定的属性清单:high 表示在一次新鲜的点击上屏幕尺寸和时区都对上了,low 表示请把它当作线索,而不是事实。
  • 窗口以小时计,不是以天计。 指纹在点击之后两小时失效,而置信度从最初的十五分钟之后就开始下降。
  • 请只在首次启动时发送一次请求。 这条记录会被第一次成功匹配消费掉;第二次调用什么也拿不到。
  • 不经过中转页、直接跳商店,能采集到的信息更少。 屏幕尺寸和时区只有在浏览器里运行的那个页面才知道,所以直接前往商店的链接只能靠语言和操作系统版本来匹配——而且它会如实说明这一点,并给出更低的置信度。

测试清单

  1. 装了应用的手机上打开链接:它应当直接落进应用里。
  2. 没装应用的手机上打开:页面短暂出现,然后应用商店打开。
  3. 从社交信息流里打开:检查你选的应用内浏览器方案是否符合预期。
  4. 在桌面浏览器里打开:应当去往桌面端目标地址,或者主目标地址。
  5. 在该域名上运行检查文件,确认两个文件都返回正常。