mailto:协议可预填邮件字段并唤起默认客户端,但需完整url编码(如&→%26)、正确分隔多收件人;tel:协议用于拨号,国际号码须带+前缀且剔除非数字字符,微信等环境需降级提示。

用 mailto: 协议打开默认邮件客户端
直接点击就能唤起系统默认邮件程序(如 Outlook、Mail.app 或手机上的 Gmail),前提是用户设备已配置好邮件账户。协议本身不发信,只预填收件人、主题、正文等字段。
常见错误是 URL 编码没做全,比如空格、中文、特殊符号(&、?)未转义,导致链接截断或参数丢失。例如:mailto:test@example.com?subject=反馈&body=你好 中的 & 会被浏览器误认为 URL 分隔符,必须写成 %26。
- 收件人地址写在
mailto:后面,多个用英文逗号分隔:mailto:a@b.com,c@d.com - 参数用
?开头,多个参数用&连接(HTML 中要写成&,不是&) -
subject和body值需手动 URL 编码,推荐用encodeURIComponent()处理,不要手写%E4%BD%A0%E5%A5%BD - 移动端 iOS 和 Android 均支持,但部分国产安卓邮箱 App 可能忽略
body参数
用 tel: 协议触发拨号界面
点击后直接跳转到系统拨号页(不会自动拨打),适用于手机端和部分桌面端(如 macOS 的 FaceTime)。这是最轻量、兼容性最好的电话调用方式。
容易被忽略的是号码格式:国际号码必须带 + 和国家代码(如 +8613812345678),否则 iOS 会拒绝识别;国内短号(如 10086、114)可不加 +,但建议统一处理。另外,号码中所有非数字字符(括号、横线、空格)应全部移除,仅保留 + 和数字。
- 基础写法:
@#@#@#@#@#@#@#@#@#@0 - 国际号码务必以
+开头:tel:+8613812345678,不能写tel:86-138-1234-5678 - 避免在
href中混入空格或中文括号,它们会导致 iOS Safari 完全不响应点击 - 某些微信内置浏览器会拦截
tel:,可加target="_blank"或配合 JS fallback 提示
为什么不用 JavaScript 模拟拨号或发邮件
有人试图用 window.location.href = 'tel:...' 或 location.assign() 包一层,其实没必要——原生 <a href="tel:..."></a> 更可靠,且能被屏幕阅读器正确识别,无障碍支持更好。
真正需要 JS 的场景只有两个:一是动态拼接号码/邮箱(比如从接口取值),二是做兼容降级(比如微信里点击弹出提示而非拨号)。但注意:iOS 上 JS 触发的 tel: 在某些 WebView 中可能被静默忽略,必须确保是用户手势(如 onclick)触发。
- 动态生成时,先校验号码格式再拼接:
`tel:${number.replace(/[^+\d]/g, '')}` - 微信内可检测
navigator.userAgent.includes('MicroMessenger'),然后改用alert()或展示二维码 - 不要用
setTimeout延迟跳转,iOS 会判定为非用户触发,协议失效
移动端真机测试最容易翻车的点
开发时在 Chrome 桌面模拟器点 tel: 看似正常,但一上真机就失灵,往往卡在三个细节上:URL 编码不完整、微信环境未适配、号码含隐藏 Unicode 字符(比如从 CMS 复制来的全角数字)。
特别是从富文本编辑器或 Excel 粘贴的电话号码,常带不可见的零宽空格(u200b)或全角数字(0123),肉眼无法识别,但会让 tel: 协议彻底失效。建议在存入数据库前就清洗,或前端用正则强转:number.replace(/[^d+]/g, '')。
- 真机测试必须覆盖 iOS Safari、Android Chrome、微信内置浏览器三类环境
- 用
console.log(encodeURI(href))打印最终生成的href值,确认没有多余空格或非法字符 - 微信中
tel:和mailto:都可能被拦截,fallback 提示文案要明确(如“请复制号码后手动拨打”)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











