nativePlugin 是唯一稳定路径:因 canvas 仅截自身元素,DOM 截图在 iOS 微信 WebView 中常白屏或报安全错误;真机分享微信必须先保存截图至相册再传路径,且需适配 iOS 权限、安卓 Scoped Storage 及图片格式限制。

uni-app 页面截图用 canvas 还是 nativePlugin?
直接说结论:纯 H5 或小程序端用 canvas + dom-to-image 类方案不可靠,iOS 微信 WebView 会截空白;真机分享微信必须走原生能力,nativePlugin 是唯一稳定路径。
原因很简单:uni-app 的 uni.canvasToTempFilePath 只能截 canvas 元素本身,不是整个页面;而 web-view 或复杂布局(如 fixed、transform、svg、跨域图片)会让 DOM 截图库在 iOS 微信里彻底失效——你看到的是白图或报错 SecurityError: The operation is insecure。
- 安卓微信内置 X5 内核对
dom-to-image支持稍好,但字体渲染、阴影、border-radius 仍常出错 - 小程序平台(微信/支付宝)可用
wx.canvasToTempFilePath+cover-view组合,但仅限自定义组件内,且不能截web-view和原生导航栏 - 真正能截全屏(含状态栏、导航栏、下拉刷新区域)+ 保存 + 分享的,只有调用原生插件,比如
uni-plugin-screenshot或自研NativePlugin
微信分享前必须先保存到相册?
是的。微信 SDK(uni.share 或 uni.openDocument)不接受内存中的图片数据,只认本地临时路径或永久路径。而原生截图插件返回的路径,iOS 是 file:// 开头,安卓是 /storage/emulated/0/... 这类绝对路径,必须先用 uni.saveImageToPhotosAlbum 存一次,再传给分享接口——否则会卡在“正在分享”或静默失败。
-
uni.share的imageUrl字段只支持网络地址或本地file://路径,但 iOS 对 file 协议校验极严,直接传截图路径大概率被拒 - 更稳妥的做法:截图 →
uni.saveImageToPhotosAlbum→ 监听 success 回调 → 用返回的savedFilePath去调uni.share - 注意安卓 10+ Scoped Storage 限制:插件返回的路径若不在公共目录(如
DCIM),saveImageToPhotosAlbum可能失败,需插件内部已适配MediaStore写入
uni-plugin-screenshot 插件怎么配才不崩溃?
这个插件在 HBuilderX 4.15+ 官方推荐,但默认配置容易在 iOS 上闪退,关键在权限和初始化时机。
- iOS 必须在
Info.plist手动加两项:NSPhotoLibraryUsageDescription(相册权限说明)和NSCameraUsageDescription(部分机型截图需触发相机权限弹窗) - 不能在
onLoad就调用截图,要等页面 DOM 渲染完成,建议用setTimeout(() => { screenshot() }, 100)或监听uni.$on('ready')(如果插件支持) - 安卓真机调试时,若用 USB 连接且开启“USB 调试”,部分厂商(华为、小米)会拦截截图系统调用,需关闭调试或换 Wi-Fi 调试
- 插件方法名是
screenshot.capture,不是screenshot.take或screenshot.shot,拼错直接undefined is not a function
截图后分享微信,为什么点开是黑图或打不开?
八成是图片格式或尺寸问题。微信客户端对分享图片有硬性限制:宽高比建议 9:16 到 16:9,单边不超过 2000px,格式必须是 .png 或 .jpg(不能是 .webp),且文件大小 ≤ 10MB。
- 原生插件默认输出
.png,但某些安卓 ROM 会强制转成.jpg并丢 alpha 通道——如果你页面有透明背景,结果就是黑底 - 解决办法:插件配置项加
{ format: 'png', quality: 1 }(如果支持),或截图后用uni.compressImage二次处理,但注意压缩可能引入新色差 - 分享时别用
uni.share的files字段传多张图——它实际只取第一张,且不校验格式;优先用imageUrl+ 单图路径 - 真机测试务必用正式版微信,开发版和体验版的图片缓存策略不同,常出现“开发版能打开,正式版打不开”的假象
最麻烦的其实是状态栏和导航栏:原生截图插件默认不包含它们,除非你显式传 { includeStatusBar: true, includeNavigationBar: true },但 iOS 16+ 某些机型会因此截到刘海区域外的乱码像素——这得靠插件底层用 UIGraphicsImageRenderer 重写截取逻辑,普通项目很难绕过去。











