uni.getClipboardData 返回纯字符串,需先清洗零宽字符和空白,再用正则粗筛,最后二次确认跳转;H5端须用 navigator.clipboard.readText() 且仅限 HTTPS 下用户点击触发。

uni.getClipboardData 读出的只是字符串,得自己校验
uni-app 没有内置 URL 类型判断 API,uni.getClipboardData 返回的 res.data 就是原始字符串,哪怕用户复制的是 https://example.com,它也还是字符串,不会自动标记为 “URL”。你必须手动做格式校验和清洗。
直接 new URL(res.data) 或 URL.canParse() 会抛错:用户可能复制了中文、空格、换行、零宽字符(如 \u200b),甚至只是“点我跳转”这种纯文本。不清洗就校验,90% 的 case 都会失败。
- 先用
.replace(/[\u200b-\u200f\u202a-\u202f\uFEFF]/g, '')清掉 iOS/微信常见零宽污染字符 - 再
.trim()去首尾空白,避免" https://a.b "这类被误判为非法 - 最后才进正则或 URL 构造器校验
用正则粗筛比 new URL() 更稳,尤其在小程序和旧 Android 上
小程序基础库和部分 Android WebView 不支持 URL.canParse,而 new URL(str) 在非法输入时直接 throw,容易崩掉逻辑。推荐用宽松正则先快速过滤明显非 URL 的内容:
/^https?:\/\/[^\s/$.?#].[^\s]*$/i —— 覆盖常见 http/https,排除空、纯域名、含空格或控制符的串
- 这个正则不追求 100% RFC 合规,而是防错:能拦住
"hello"、"123"、" "、"https://" - 如果业务允许短链或带端口(如
http://localhost:8080),可放宽为/^https?:\/\/[\w.-]+(?:\:[0-9]+)?(?:\/[^\s]*)?$/i - 别用
.test(window.location.href)这类动态测试,剪贴板内容不可控,必须对res.data单独处理
校验后还要防“伪 URL”,比如用户复制了带链接的富文本
用户从微信公众号、钉钉文档里复制一段话,看着像 URL,实际是「<a href="xxx">点击访问</a>」或「? https://xxx」——正则能过,但粘贴到输入框里根本不能直接跳转。
- 建议加一层语义清洗:用
res.data.replace(/]*>/g, '').replace(/?|?|?/g, '').trim()剥离 HTML 标签和 emoji 前缀 - 如果清洗后长度骤减(比如原长 50,清洗后只剩 10),说明原文本含大量非 URL 内容,应视为无效
- 关键场景(如跳转页)必须让用户二次确认:
uni.showModal({ title: '检测到链接', content: '是否前往 ' + cleanedUrl + '?' }),不能自动跳
H5 平台读剪贴板受限,别依赖 onShow 自动读
H5 端根本无法调用 uni.getClipboardData,它返回空或静默失败。必须降级用 navigator.clipboard.readText(),但有两个硬约束:
- 仅 HTTPS 环境可用,
http://localhost会报NotAllowedError - 必须由用户点击事件同步触发,不能放在
onShow、setTimeout或Promise.then里 - iOS Safari 对
readText()调用更敏感,若页面刚加载完立刻读,可能拿到上一页残留内容
所以“判断是否为 URL”这个动作,只能绑定在明确的用户操作上,比如「粘贴链接」按钮,而不是试图在页面显示时自动识别——那既不可靠,又违反平台策略。
真正容易被忽略的点是:URL 校验不是终点,清洗和上下文才是。用户复制的内容永远比你预设的格式更混乱,多一次 replace 和一次 trim,比写十个正则都管用。


















