前端常见问题
H5 唤起移动端 App
H5 网页唤起本地 App,是活动页、营销落地页跳转自家或第三方客户端时的常见需求。
主流实现有三套:URL Scheme、iOS Universal Link、Android App Links。微信内置浏览器另有开放标签 wx-open-launch-app。
URL Scheme
URL Scheme 是 iOS 与 Android 都支持的原生机制。App 在开发阶段注册自定义 Scheme;H5 打开该协议链接,系统匹配已安装的 App,拉起后可带参数进指定页。
tel: 拨打电话(标准写法是 tel:,不是 tel://)
sms: 发送短信
weixin:// 唤起微信
alipay:// 唤起支付宝
taobao:// 唤起淘宝
mqq:// 唤起 QQ
zhihu:// 唤起知乎
<!-- 直接用 a 标签触发 -->
<a href="zhihu://">打开知乎 App</a>
<!-- 脚本触发 -->
<script>
location.href = "zhihu://";
</script>
存在的缺陷:
- App 未安装时表现不可控:不同手机、浏览器差异很大,有的报链接错误、跳到空白页,很难优雅降级到下载页。
- 冲突:多个 App 注册完全相同的 Scheme 时,系统选哪一个打开并不由页面控制。
- WebView 限制:旧版
UIWebView下部分场景跳不过。现行 iOS 只用WKWebView,UIWebView已废弃。 - 平台拦截:微信、QQ 浏览器、手机百度等国内环境会直接禁用自定义 Scheme,H5 里打不开 App。
正因为这些短板,苹果和 Android 分别推出基于 HTTPS 的替代:Universal Link(iOS)、App Links(Android)。
Universal Link(iOS 9+)
Universal Link 是 iOS 9 推出的通用链接,用标准 https 域名唤起 App,不再依赖自定义协议头。
- 已安装 App:直接唤起,按链接路由打开对应页面
- 未安装 App:在浏览器打开该 https 页,可配成下载页或活动落地页
核心优势:
- 使用标准 HTTPS,多数平台不会当「非法协议」拦截。微信对 Universal Link 曾逐步放开,但会话里点开的网页等场景仍常被拦,要稳定唤起仍用开放标签。
- 网页无法探测本机是否安装了 App。
- 支持
WKWebView(以及历史上的UIWebView),链接可被搜索引擎索引。
必要部署条件:
- 可访问的 HTTPS 域名
- 在域名根目录或
/.well-known/放置苹果规定的apple-app-site-association(JSON,通常无后缀) - Xcode 开启 Associated Domains,配置对应域名
Android App Links(Android 6.0+)
Android 6.0 引入的 App Links 同样基于 HTTPS 域名校验,用来替代传统 URL Scheme。域名校验通过后,点击链接直接打开 App,不再弹出「选浏览器还是选应用」。
主要限制:
- 国内 Android 碎片化:部分国产浏览器、WebView 对 App Links 支持不完整,会只在浏览器里打开网页。
- 用户记住了选择:系统曾弹出选择框,用户勾选「记住」并选了浏览器后,之后该链接会一直在浏览器打开。可在系统应用设置里改默认打开方式,并不是永远不能改。
部署条件:
- HTTPS 域名,服务器放置
/.well-known/assetlinks.json AndroidManifest.xml里配置intent-filter,声明对应域名
Universal Link 和 App Links 是现行优先方案。Android 受厂商 ROM、浏览器影响,做不到完全可靠。业务上一般:先走通用链接,超时再落到下载页。
微信内置浏览器唤起 App
自定义 Scheme 在微信里会被拦。要在微信 H5 里稳定唤起 App,用官方开放标签 wx-open-launch-app(需 JS-SDK,wx.config 的 openTagList 包含该标签)。
使用前置条件:
- 公众号:已认证的服务号;订阅号不支持
- 微信开放平台账号必须认证;服务号与开放平台账号主体必须完全一致
- 在开放平台绑定:
管理中心 → 公众账号详情 → 接口信息 → 网页跳转移动应用 → 关联设置,绑上要唤起的 App - H5 域名配成公众号的 JS 接口安全域名
<wx-open-launch-app
app-id="wxxxxxxx"
extinfo="自定义透传参数"
>
<script type="text/wxtag-template"></script>
</wx-open-launch-app>
平台差异:
- Android:被唤起的 App 必须接入微信 OpenSDK,并配置
WXEntryActivity。 - iOS:不靠 OpenSDK 接标签,靠 Universal Link 唤起,Associated Domains 仍要配好。
常见问题:
- 访问来源:在聊天会话里点链接打开的页面,标签唤不起 App。允许的方式包括:公众号消息卡片、扫码、从分享打开的页面。
- Android 上常见:App 要在后台还活着才唤得起(需客户端配合);iOS 无此限制。
- 标签只提供按钮,不能用脚本自动点,必须用户亲手点。
SPA 和 MPA 的区别
SPA(单页应用)
SPA(Single-Page Application,单页应用)整个站点只有一个 HTML 入口。交互不整页刷新,由 JS 更新当前页 DOM;HTML、JS、CSS 在首次访问时加载,或在操作后再按需加载。
MPA(多页应用)
MPA(Multi-Page Application,多页应用)由多个独立 HTML 页面组成。跳转会整页请求,浏览器重新加载该页的 HTML、CSS、JS。
| 对比项 | SPA 单页应用 | MPA 多页应用 |
|---|---|---|
| 页面渲染方式 | 仅首次加载 HTML,JS 更新 DOM,无整页刷新 | 跳转即整页刷新,每页一份 HTML |
| 资源加载 | 首屏加载框架、路由、组件,后续可懒加载 | 访问哪页就加载哪页的资源 |
| 页面跳转 | 前端路由,无整页白屏刷新 | 浏览器原生跳转,有刷新 |
| SEO | 空壳 HTML 对爬虫不友好,要额外方案 | 每页实 HTML,搜索引擎更好抓 |
| 服务器路由 | history 要后端配合;hash 不用特殊配置 |
每页对应真实 URL,不必为前端路由单独兜底 |
SPA 实现 SEO
- SSR(服务端渲染):请求到达服务器时,服务端执行 Vue、React 组件、拉接口,生成完整 HTML 再返回。代表:Nuxt(Vue)、Next.js(React)。
- SSG(静态站点生成):构建阶段把页面渲染成静态 HTML 放到磁盘,访问时由 Web 服务器直接吐文件。
- URL 重写(伪静态):磁盘上没有对应的静态 HTML。Nginx、Apache 用 Rewrite 把「像静态页的 URL」转给后端(PHP、Java),由模板查数据再输出 HTML。这是传统多页站点的做法,跳转仍会整页刷新,不是 SPA 自己的渲染模式。
Googlebot 会执行 JS,但抓取时效和完整性仍不如首包就是完整 HTML。国内搜索引擎对纯客户端渲染更不稳,要收录仍优先 SSR 或 SSG。
SPA 的优缺点
优点:切换流畅。框架和公共组件首屏加载一次;路由只改局部 DOM,少整页白屏,交互接近桌面软件。
缺点:
- 首屏体积大:要下载运行时、路由、业务代码,容易白屏;用分包懒加载、骨架屏缓解。
- SEO:入口 HTML 常是空壳,内容等 JS 跑完才有。不能假定所有爬虫都把 JS 执行完整。
- 前端路由要后端配合
history模式:URL 不带#,服务器上没有对应文件;刷新会 404,需把这些路径都回落到 SPA 入口 HTML。hash模式:地址带#,观感差,易和页内锚点冲突,部分统计、分享工具也不友好。
- 前进、后退、表单状态、滚动位置、弹层等浏览器原生行为不会自动按「页」恢复,要业务自己维护。
- 内存:SPA 不整页销毁,只换视图。路由切换时组件、定时器、监听、第三方实例若没拆干净,内存会涨,页面越来越卡。