uni.setclipboarddata与plus.runtime.openurl必须分两步显式调用,二者无隐式依赖,且均需在用户手势触发的同步上下文中执行;需严格按平台判断并隔离代码,h5端禁用plus api,app端须确保plusready就绪,ios系统级隔离导致无法自动读取剪贴板内容。

uni.setClipboardData 和 plus.runtime.openURL 必须分两步调用
不能指望复制完自动触发 APP 唤起——uni.setClipboardData 和 plus.runtime.openURL 是两个完全独立的异步操作,没有隐式依赖关系。你必须显式控制执行顺序,且二者都需在用户手势上下文中触发(比如按钮 @tap),否则 H5 端静默失败、App 端可能被系统拦截。
常见错误是把 plus.runtime.openURL 放在 uni.setClipboardData 的 success 回调里却没做平台判断,结果在小程序里直接报错 plus is not defined;或者在 H5 端调了 plus 方法却无任何反应。
- 必须用
uni.getSystemInfoSync().platform或process.env.UNI_PLATFORM明确区分运行环境 - H5 端禁止调用任何
plus.*API,否则会中断执行或报 ReferenceError - App 端调用
plus.runtime.openURL前,需确保plusready事件已触发(尤其在页面生命周期早期调用时)
复制后唤起淘宝/微信/支付宝等三方 APP 的 scheme 写法差异
不同 APP 注册的自定义协议(scheme)格式不统一,且 iOS 和 Android 对参数编码、空格、特殊字符的处理也不一致。直接拼接字符串极易失败,比如淘宝的 taobao://s.taobao.com/search?q=uni-app 在 iOS 上可能因未 encodeURI 而截断。
关键点不是“能不能写”,而是“写对没”。以下为实测有效的 scheme 示例:
- 淘宝搜索:
taobao://s.taobao.com/search?q=+encodeURIComponent('uni-app') - 支付宝转账:
alipays://www.alipay.com/?q=+encodeURIComponent('apay://pay?payto=xxx&amount=1') - 微信打开聊天页:
weixin://dl/chat?username=xxx(仅限已安装且有权限的场景,iOS 限制极严)
注意:plus.runtime.openURL 的 errorCB 回调里一定要打印 res.message,很多失败不是因为 scheme 错,而是目标 APP 未安装、Android 包名不匹配、或 iOS 被 ATS(App Transport Security)策略拦截。
为什么 copy + open 组合在 iOS App 上大概率失败
iOS 系统对跨进程数据共享极为敏感。即使你成功调用 uni.setClipboardData,后续 plus.runtime.openURL 启动的第三方 APP 也无法直接读取剪贴板内容——这是系统级隔离,uni-app 无法绕过。
所谓“复制后自动打开并粘贴”,本质是误导性需求。真实可行路径只有两条:
- 把要传递的数据作为 URL 参数附在 scheme 后(如
myapp://action?code=abc123),由目标 APP 自行解析 - 改用深度链接(Deep Link)+ Universal Links(iOS)或 App Links(Android),通过服务端跳转携带参数,避开剪贴板
强行在 iOS 上依赖剪贴板传参,等于假设用户会在唤起后手动切回你的 APP 粘贴——这违背“自动”初衷,也大幅降低转化率。
Android 端唤起失败的三个隐蔽原因
Android 表面兼容性好,但实际踩坑更多。以下问题不会报错,只会白屏或跳转到浏览器:
-
plus.runtime.openURL的identity参数填了包名但大小写错误(如com.Taobao.taobao≠com.taobao.taobao) - 目标 APP 的
AndroidManifest.xml未声明android:exported="true"(Android 12+ 强制要求) - HBuilderX 打包时未在
manifest.json → App SDK 配置 → URL Scheme中添加对应 scheme 白名单(部分厂商 ROM 会拦截未声明的 scheme)
验证方式:用 ADB 命令手动触发一次 adb shell am start -W -a android.intent.action.VIEW -d "taobao://...",看是否真能拉起。如果命令行能行而 uni-app 不行,基本锁定是 plus 初始化或参数传递问题。
最易被忽略的一点:H5 页面里永远不要写 plus 相关逻辑。哪怕加了 if (uni.getSystemInfoSync().platform === 'app') 判断,代码仍会被 H5 端 JS 引擎解析——只要存在未定义的 plus 引用,就可能引发 SyntaxError 或阻塞后续执行。务必用动态 require 或条件编译 /* #ifdef APP-PLUS */ 包裹。











