uni-app无法直接网页截图,需分平台实现:H5用html2canvas(仅限viewport内DOM),小程序需Skyline渲染+snapshot组件,App端必须用原生插件如uni-plugin-screenshot。

不能直接“把网页截图”,uni-app 里没有浏览器级的 capturePage 能力;所谓“网页截图”,本质是根据不同平台,用对应手段把当前视图内容渲染成图片——H5 用 html2canvas 模拟,小程序靠 canvas + DOM 查询,App 端必须调原生 API。
uni-app H5 端用 html2canvas 截图
H5 是唯一能“近似整页截图”的环境,但仅限于当前 viewport 内可见 DOM,不包含 video、iframe、Canvas 内容,也不反映滚动偏移量。
- 必须安装并引入:
npm install html2canvas@1.4.1(高版本对 uni-app 的 rpx 支持不稳定) -
useCORS: true才能加载跨域图片,否则留白;allowTaint: true绕过 canvas 污染限制 - 别传
document.body—— uni-app 的根节点是#app,但实际内容在.uni-app或你自己的容器 ref 下,建议用this.$refs.target显式指定区域 - 导出后不能直接调
uni.saveImageToPhotosAlbum(H5 不支持),得用<a download></a>触发下载,或转 base64 后用uni.downloadFile中转
微信小程序端必须配 Skyline 才能真截图
默认 WebView 渲染下,takeSnapshot 不生效,uni.canvasToTempFilePath 只能截 canvas 自身,且极易黑屏。
- manifest.json 里加:
"mp-weixin": { "rendererOptions": { "skyline": { "sdkVersionBegin": "3.0.1" } } } - pages.json 对应页面加:
"renderer": "skyline"和"componentFramework": "glass-easel" - 模板中用
<snapshot></snapshot>包裹目标区域(不是<view></view>),再调uni.createSelectorQuery().select('#snapshotId').fields({ snapshot: true }) - 别漏掉
fileType: 'png'参数,即使文档写“默认 png”,低基础库会静默失败
App 端(iOS/Android)必须走原生插件
uni.canvasToTempFilePath 在 App 端返回空白或黑图是常态,因为 web-view 和原生渲染层隔离,canvas 根本看不见导航栏、map、video 等原生组件。
- 官方没封装,
uni.getScreenCapture在 App 端根本不存在,调用即报is not a function - 推荐用
uni-plugin-screenshot:iOS 走UIApplication.shared.keyWindow,Android 走View.getRootWindow(),自动避开状态栏遮挡 - Android targetSdkVersion ≥ 30 时,需在
AndroidManifest.xml声明android.permission.READ_MEDIA_IMAGES,否则保存失败无提示 - 截图返回的是
file://本地路径,不能直接传给uni.uploadFile—— 必须先uni.getFileInfo拿 size,否则上传中断
为什么局部截图总黑屏或尺寸错乱
不是代码写错了,而是 uni-app 的单位系统和渲染时机在各平台表现不一。
- 用
uni.createSelectorQuery获取元素位置时,top/left返回的是逻辑像素(rpx),但 canvas 绘制需要物理像素(px),必须乘以uni.getSystemInfoSync().pixelRatio -
v-show会让 canvas 的display: none,导致getContext('2d')返回 null;要用v-if控制挂载时机 - nvue 页面必须用
native-canvas类型,web canvas API 在 nvue 下完全不可用 - 滚动中截图,
boundingClientRect拿到的是静态位置,若要截整个长列表,得自己计算 scrollHeight + 多次 drawImage 拼接,成本高且易失真
最易被忽略的一点:App 端截图结果依赖当前 window 的层级快照,如果页面里用了 uni.showModal 或自定义弹窗,它们可能不在 keyWindow 里,截图就漏掉了——这种问题只能靠原生插件扩展能力,JS 层无解。


















