必须手动用 canvas 绘制海报并上传 cdn,因 wxml2canvas 依赖微信原生 api,在 uni-app 多端不兼容;需先下载资源、统一 px 单位、文字换行处理,并严格完成上传 https 直链三步流程,且 manifest.json、pages.json、公众号后台三处分享开关及 onshareappmessage 必须同时配置。

不能直接用页面截图或 wxml2canvas 生成朋友圈海报,必须走 canvas 手动绘制 + 上传 CDN 的链路。否则 onShareTimeline 的 imageUrl 字段会失效,卡片降级为纯文字。
为什么 wxml2canvas 在 uni-app 里跑不通
wxml2canvas 是微信原生小程序的库,依赖 WXML 节点树和 SelectorQuery API。uni-app 编译到 H5、App 或非微信平台时,根本不存在等价的节点上下文;即使在微信小程序平台,也常因 cover-view 不支持、节点未就绪、rpx 单位错乱导致白屏或缺元素。
常见错误现象:ctx.draw 后 canvas 内容为空、uni.canvasToTempFilePath 成功回调不触发、朋友圈卡片只显示默认图标。
替代方案只有一个:放弃“还原页面”,改用 uni.createCanvasContext 逐项绘制——图片、文字、二维码、圆角矩形,全部靠坐标和像素控制。
canvas 绘制海报的关键实操要点
手动绘制不是麻烦,而是可控。重点不在“怎么画”,而在“怎么确保每一步都稳”:
-
uni.getImageInfo必须先调,拿到网络图宽高再传给drawImage;否则 H5 端可能跨域失败,小程序端可能静默留空 - 所有网络资源(头像、背景、二维码)必须先
uni.downloadFile下载到本地临时路径,再传给drawImage;小程序不认 HTTP URL 直接绘图 - 二维码建议用
qrcode.js生成 base64,再用uni.getFileSystemManager().writeFile写入临时文件,避免后端拼图带来的鉴权和防盗链问题 -
canvasWidth和canvasHeight单位必须是 px,别写 rpx;不同设备 DPR 差异大,统一按物理像素算(比如固定 750×1000) - 文字换行自己拆:用
ctx.measureText测单行宽度,按字数或字符切分,ctx.fillText多次调用
onShareTimeline 的 imageUrl 必须是 HTTPS 直链,且要上传
很多人卡在这步:canvas 绘制完 → uni.canvasToTempFilePath 得到 tempFilePath → 直接塞进 onShareTimeline 返回对象。结果朋友圈卡片还是没图——因为微信根本不认本地路径。
正确流程只有这一条:
- canvas 绘制完成
- 调
uni.canvasToTempFilePath生成临时文件 - 用
uni.uploadFile把该文件上传到你自己的 CDN 或云存储(如腾讯云 COS、阿里 OSS) - 拿到返回的 HTTPS 地址(注意必须是公网可直访、无鉴权、无重定向)
- 在
onShareTimeline中返回{ imageUrl: 'https://xxx.com/poster-abc.png' }
漏掉上传这步,imageUrl 就是无效的。另外注意:该地址图片尺寸建议 ≥ 800×800 px,否则朋友圈卡片可能压缩变形或被截断。
三重权限开关缺一不可,且无报错提示
onShareTimeline 不是写了就能用。它需要 manifest.json、pages.json、微信公众平台后台三处同时开启,任意一项没对上,右上角菜单里“分享到朋友圈”入口就消失,且控制台完全静默。
-
manifest.json中 “Share(分享)” 模块已勾选,“微信分享”项填了正确appid -
pages.json对应页面配置了"enableShareTimeline": true(不是enableShareAppMessage) - 微信公众平台后台 → 小程序设置 → 功能设置 → “分享到朋友圈”开关已手动开启(2026 年仍需人工操作)
还有一个硬性要求:必须同时定义 onShareAppMessage,哪怕只返回空对象。否则真机运行时,朋友圈入口压根不渲染。
最容易被忽略的是上传后的 HTTPS 地址校验——别只看能不能在浏览器打开,还要确认响应头含 Content-Type: image/png 且无重定向跳转。朋友圈卡片加载失败时,不会报错,只会默默回退成文字链接。










