- 如何实现快速生成朋友圈海报分享图
由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 Canvas 功能生成一张带有小程序码的图片,然后引导用户下载图片到本地后再分享到朋友圈。相信大家在绘制分享图中应该踩到 Canvas 的各种(坑)彩dan了吧~ 这里首先推荐一个开源的组件:painter(通过该组件目前我们已经成功在支付宝小程序上也应用上了分享图功能) 咱们不多说,直接上手就是干。 [图片] 首先我们新增一个自定义组件,在该组件的json中引入painter [代码]{ "component": true, "usingComponents": { "painter": "/painter/painter" } } [代码] 然后组件的WXML (代码片段在最后) [代码]// 将该组件定位在屏幕之外,用户查看不到。 <painter style="position: absolute; top: -9999rpx;" palette="{{imgDraw}}" bind:imgOK="onImgOK" /> [代码] 重点来了 JS (代码片段在最后) [代码]Component({ properties: { // 是否开始绘图 isCanDraw: { type: Boolean, value: false, observer(newVal) { newVal && this.handleStartDrawImg() } }, // 用户头像昵称信息 userInfo: { type: Object, value: { avatarUrl: '', nickName: '' } } }, data: { imgDraw: {}, // 绘制图片的大对象 sharePath: '' // 生成的分享图 }, methods: { handleStartDrawImg() { wx.showLoading({ title: '生成中' }) this.setData({ imgDraw: { width: '750rpx', height: '1334rpx', background: 'https://qiniu-image.qtshe.com/20190506share-bg.png', views: [ { type: 'image', url: 'https://qiniu-image.qtshe.com/1560248372315_467.jpg', css: { top: '32rpx', left: '30rpx', right: '32rpx', width: '688rpx', height: '420rpx', borderRadius: '16rpx' }, }, { type: 'image', url: this.data.userInfo.avatarUrl || 'https://qiniu-image.qtshe.com/default-avatar20170707.png', css: { top: '404rpx', left: '328rpx', width: '96rpx', height: '96rpx', borderWidth: '6rpx', borderColor: '#FFF', borderRadius: '96rpx' } }, { type: 'text', text: this.data.userInfo.nickName || '青团子', css: { top: '532rpx', fontSize: '28rpx', left: '375rpx', align: 'center', color: '#3c3c3c' } }, { type: 'text', text: `邀请您参与助力活动`, css: { top: '576rpx', left: '375rpx', align: 'center', fontSize: '28rpx', color: '#3c3c3c' } }, { type: 'text', text: `宇宙最萌蓝牙耳机测评员`, css: { top: '644rpx', left: '375rpx', maxLines: 1, align: 'center', fontWeight: 'bold', fontSize: '44rpx', color: '#3c3c3c' } }, { type: 'image', url: 'https://qiniu-image.qtshe.com/20190605index.jpg', css: { top: '834rpx', left: '470rpx', width: '200rpx', height: '200rpx' } } ] } }) }, onImgErr(e) { wx.hideLoading() wx.showToast({ title: '生成分享图失败,请刷新页面重试' }) //通知外部绘制完成,重置isCanDraw为false this.triggerEvent('initData') }, onImgOK(e) { wx.hideLoading() // 展示分享图 wx.showShareImageMenu({ path: e.detail.path, fail: err => { console.log(err) } }) //通知外部绘制完成,重置isCanDraw为false this.triggerEvent('initData') } } }) [代码] 那么我们该如何引用呢? 首先json里引用我们封装好的组件share-box [代码]{ "usingComponents": { "share-box": "/components/shareBox/index" } } [代码] 以下示例为获取用户头像昵称后再生成图。 [代码]<button class="intro" bindtap="getUserInfo">点我生成分享图</button> <share-box isCanDraw="{{isCanDraw}}" userInfo="{{userInfo}}" bind:initData="handleClose" /> [代码] 调用的地方: [代码]const app = getApp() Page({ data: { isCanDraw: false }, // 组件内部关掉或者绘制完成需重置状态 handleClose() { this.setData({ isCanDraw: !this.data.isCanDraw }) }, getUserInfo(e) { wx.getUserProfile({ desc: "获取您的头像昵称信息", success: res => { const { userInfo = {} } = res this.setData({ userInfo, isCanDraw: true // 开始绘制海报图 }) }, fail: err => { console.log(err) } }) } }) [代码] 最后绘制分享图的自定义组件就完成啦~效果图如下: [图片] tips: 文字居中实现可以看下代码片段 文字换行实现(maxLines)只需要设置宽度,maxLines如果设置为1,那么超出一行将会展示为省略号 代码片段:https://developers.weixin.qq.com/s/J38pKsmK7Qw5 附上painter可视化编辑代码工具:点我直达,因为涉及网络图片,代码片段设置不了downloadFile合法域名,建议真机开启调试模式,开发者工具 详情里开启不校验合法域名进行代码片段的运行查看。 最后看下面大家评论问的较多的问题:downLoadFile合法域名在小程序后台 开发>开发设置里配置,域名为你图片的域名前缀 比如我文章里的图https://qiniu-image.qtshe.com/20190605index.jpg。配置域名时填写https://qiniu-image.qtshe.com即可。如果你图片cdn地址为https://aaa.com/xxx.png, 那你就配置https://aaa.com即可。
2022-01-20 - 【集合】花了 3 个月,写了 40 篇小程序文章
前言 花了3个月,一共输出 40 篇文章,这也算是一个阶段性的总结。在此做个文章分类集合,希望对大家有所帮助。 小程序前端 《专治按钮效果不明显(扩散动画效果)》 《小程序开发必备,这 5 款超实用开源插件!》 《仿抽奖助手奖品详情页面向上翻页效果》 《推荐 5 款高仿知名应用的开源项目!》 《生成海报很复杂?有它轻松搞定!》 《推荐一个自定义导航栏开源库》 《前端开发,必备的学习网站!》 《情侣券-领取动画分析》 《通过玩游戏来学习CSS》 《CSS不规范导致的布局显示问题》 《微信小程序如何引入npm包?》 《情侣券-选中卡片翻转动画》 《CSS:实现卡片洗牌效果》 《情侣券 v2.0 使用的 4 款开源组件》 小程序云开发 《使用聚合函数实现打卡排行榜》 《使用云开发做内容安全检查》 《云开发-实现分页功能》 《云开发-实现维护用户表》 《云开发-实现模糊搜索》 《云开发实战:实现订阅消息推送》 《如何优雅的调用云函数?》 《云开发实战-如何维护用户表?(优化版)》 《推荐 10 款使用云开发的开源项目》 《云开发:CloudBase CMS 实战使用指南》 小程序产品 《如何利用小程序提高10倍活动效果?》 《实战:让数据说话之自定义埋点分析》 《#小程序云开发挑战赛#-情侣券》 《小程序运营必备的 3 款官方小程序》 《小程序云开发挑战赛:情侣券 v1.1 版本迭代》 《云开发挑战赛复赛:情侣券介绍PPT》 《参加#小程序云开发挑战赛#复赛收获》 《云开发挑战赛决赛:情侣券介绍PPT》 通用知识 《如何重构?》 《如何高效学习?》 《如何看懂时序图?》 《为什么优秀的程序员都写博客?》 《我从 Android 转到 微信小程序 的思考》 最后 后续计划会写更多云开发相关的文章以及小程序基础系列学习文章。
2020-11-24 - 微信小程序开放「分享到朋友圈」功能
2020年7月7日(据说是6日深夜),一个很特别的日子,微信低调地放开了一个功能:微信小程序“分享到到朋友圈”,这个看似微小的变化,对微信小程序来说意义重大。 用fenng大的话说就是: [图片] 目前此功能没有完全放开,需微信安卓7.0.16版本才支持,灰度测试 ,iOS版本暂不支持。 想让小程序提供“分享到朋友圈”的功能,小程序端需要通过调用wx.showShareMenu 这个api,支持此功能,具体的操作步骤如下: 1.设置“调试基础库”的版本wx.showShareMenu api支持分享朋友圈的功能参数“[代码]menus[代码]”需要基础库2.11版本以上,因此首先在微信小程序开发工具里设置基础库为2.11版本以上 [图片] 设置完成后,在点击小程序右上角的三个点,会出现“分享到朋友圈”的按钮,不过是灰色的,无法触发。 [图片] 2.调用wx.showShareMenu api在需要转发的页面的onLoad(onShow也可以)事件里加入如下代码: [代码]wx.showShareMenu({[代码] [代码]withShareTicket:true,[代码] [代码]menus:['shareAppMessage','shareTimeline'][代码] }) 加入后,点击小程序右上角的三个点“分享到朋友圈”按钮就可以使用了 [图片] 在开发工具里可以预览分享的效果 [图片] 小程序提交审核发布后,在朋友圈里的分享效果如下 [图片] 分享后的封面图是默认小程序的logo,标题是默认当前分享的小程序的页面导航标题。 点击打开小程序后,跳转到分享的小程序页面,点击不能直接使用小程序的跳转,需要点击下方的“前往小程序”才是真正进入小程序。 [图片] 这个功能目前还有完善,在开发工具里里查看小程序的分享页,如果小程序里有“updateManager.onUpdateReady”方法来更新小程序,会提示报错: [代码]Cannot read property 'onUpdateReady' of undefined[代码] 目前小程序分享到到朋友圈的方式是:小程序单页模式,并不会直接打开小程序,无法交互。“单页模式”下,页面顶部固定有导航栏,标题显示为分享时的标题,非常适合阅读类、内容类、资讯类小程序;顶部导航栏与底部操作栏均不支持自定义样式。以后开发需要考虑单页模式的布局,同时也要考虑专门为转发朋友圈来设计页面导航标题。 有关单页面模式的适配和限制详见微信官方文档: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html 以上这些功能设计,就是微信防止此功能的滥用。 3.自定义分享的封面、标题和页面参数可以使用页面的分享朋友圈事件处理函数:onShareTimeline(), 编写方法参考微信开发文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareTimeline [图片] 微信小程序都推出3年了,但转发一直不能转发到朋友圈,总算开了这个口子,这对小程序来说是巨大的利好,相信后续会不断完善,既增加小程序的曝光率,也防止滥用,这点我对微信的产品设计有信心,此前一直都非常克制。 微慕小程序所有版本已经支持转发的到朋友圈,详情见:https://www.minapper.com/
2020-07-13 - 社区每周 | 云开发资源扶持计划上线、微信学院课程系列更新与上周社区问题反馈(10.28-11.1)
各位微信开发者: 以下是上周小程序相关能力更新及我们在社区收到的问题反馈、需求的处理进度,希望同大家一同打造小程序生态。 小程序·云开发资源扶持计划上线 为助力开发者以更低的门槛、更低的成本快速构建小程序,小程序·云开发将为满足申请条件的小程序提供为期一年的资源支持。对于满足申请条件的小程序,可在云开发控制台申请价值 104 元/月或 860 元/月的代金券。申请成功后每月将发放一张代金券,持续发放12个月。其中,代金券申请标准为: - 专业版(104 元/月):最近 31 天,连续 5 天每天记录到用户访问中的独立访客(UV)不低于 100 的小程序。 - 旗舰版(860 元/月):最近 31 天,连续 5 天每天记录到用户访问中的独立访客(UV)不低于 2000 的小程序。 发放的代金券可用于抵扣云开发套餐购买金额。开发者可通过下载最新 Nightly 版开发者工具进行代金券申请。详细代金券功能介绍请参考文档《小程序·云开发代金券》 。 社区「微信学院」支持课程系列微信学院现已支持课程系列,如《小程序开发起步》、《WeChat Mini Program Development》等,欢迎广大开发者点播学习。 上周问题反馈和处理进度(10.28-11.01)已修复的问题swiper 组件 bindanimationfinish 点击就会触发的问题 查看详情 map 组件 maker 支持云存储的图片 id 的问题 查看详情 editor 插入图片位置错误的问题 查看详情 基础库 2.9.1中使用数据路径形式去 setData,性能会发生断崖式下跌的问题 查看详情 微信支付成功后没有回调的问题 查看详情 小程序开发真机调试 wx.login 调用无响应的问题 查看详情 后台实时日志显示不出来的问题 查看详情 小程序管理后台图标问题 查看详情 下个基础库修复Android textarea 移动光标不应触发 input 事件的问题 查看详情 textarea 修改样式失效的问题 查看详情 安卓 wx.scanCode datamatrix 类型二维码, 逗号后数据丢失的问题 查看详情 修复中的问题在使用 input 组件拉起软件盘时出现短暂的部分黑屏的问题 查看详情 wx.getLocation 接口得到的 altitude 为 0 的问题 查看详情 Button 拉起 APP 功能嵌套在 cover-view 时失效的问题 查看详情 input 组件在输入文字后锁屏,解锁后不走 bindconfirm 事件的问题 查看详情 小游戏调用云函数报错,500Error 的问题 查看详情 微信7.0.7 很多小游戏会死机的问题 查看详情 picker 多列选择器的问题 查看详情 新建微信小游戏后出现的问题 查看详情 video 组件安卓无法播放直播视频的问题 查看详情 Object.values undefined 的问题 查看详情 微信小游戏部分安卓机型的授权按钮 createUserInfoButton 不显示的问题 查看详情 开发文档扩展功能扫码没有页面的问题 查看详情 安卓微信版本7.0.8 textare 组件 自动弹出键盘 不输入 点击收起键盘 占位符被清空的问题 查看详情 在安卓vivo x 20 textare 的 placeholder 不显示的问题 查看详情 陀螺仪组件停止监听异常的问题 查看详情 开发者工具更新到最新版后,不可进入问的问题 查看详情 新版 Canvas 的 createImageData 方法返回的 imageData.data 属性不能修改的问题 查看详情 Android 手机微信网页白屏的问题 查看详情 使用开发者工具命令行上传代码提示 socket hang up 的问题 查看详情 部分音频苹果手机不能背景音乐播放的问题 查看详情 需求反馈已支持image 组件设置预加载屏数的需求 查看详情 需求评估中模板消息申请申请记录,查看进度的需求 查看详情 采用微信提供的自定义 tabBar,可以动态地修改跳转路径的需求 查看详情 微信开发者工具的编辑器功能可以提供当前打开文件的列表的需求 查看详情 wx.getSystemInfoSync 拿到的信息中 language 字段的取值的需求 查看详情 wx.getSystemInfo 的回调参数提供允许微信使用蓝牙的开关的需求 查看详情 小程序用户反馈的日志文件更加可视化、可定位的需求 查看详情 能在音频播放中加入 endTime 的需求 查看详情 小程序 map 使用因为 marker 数量太大几万个,加图层尼的需求 查看详情 关于长期订阅模板的申请-教育类-作业提醒的需求 查看详情 希望小程序提供设置页面为横屏 API 的需求 查看详情 强行热更能支持真机调试的需求 查看详情 readFile 方法提供读取的位置和读取长度的需求 查看详情 订阅消息将选择权交给用户的需求 查看详情 建议 css 的 import 语法支持子作用域 查看详情 camera 组件功能支持更多功能的需求 查看详情 小游戏PC端后台统计支持导出功能的需求 查看详情 微信团队 2019.11.07
2019-11-08 - 小程序前后端交互使用JWT
前言 现在很多Web项目都是前后端分离的形式,现在浏览器的功能也是越来越强大,基本上大部分主流的浏览器都有调试模式,也有很多抓包工具,可以很轻松的看到前端请求的URL和发送的数据信息。如果不增加安全验证的话,这种形式的前后端交互时候是很不安全的。 相信很多开发小程序的开发者也不一定都是大神,能够精通前后端,作为小程序的初学者不少人也是根据官方的文档去学习开发的。我自己最开始接触小程序也是从wafer2开始的,那时候腾讯云提供的SDK包含PHP和Node.js,因为对于一直做前端的人来说,Node.js的学习成本比较低,只要会JS基本能看懂,也是从那时候才开始接触Node.js,所以本文主要是基于wafer2的服务端基于Koa2的后端来说(其实这个不重要,Node.js基本都差不多)。 什么是JWT? 根据维基百科的定义,JSON WEB Token,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。 为什么使用JWT? 首先,这不是一个必选方案。有时候我们的API是其它服务端和小程序公用的,那么就涉及到安全验证的问题了。 微信官方不鼓励小程序一打开就要求必须登陆的方式去获取用户信息,因此我们也不能去校验这个用户是否有权限访问这个接口,但是有的接口又不能让任何人随便去看或者被随意采集。 基于token(令牌)的用户认证 用户输入其登录信息 服务器验证信息是否正确,并返回已签名的token token储在客户端,例如存在local storage或cookie中 之后的HTTP请求都将token添加到请求头里 服务器解码JWT,并且如果令牌有效,则接受请求 一旦用户注销,令牌将在客户端被销毁,不需要与服务器进行交互一个关键是,令牌是无状态的。后端服务器不需要保存令牌或当前session的记录。 关于JWT的详细介绍网上有很多,这里也就不说了,下面介绍在Koa2框架里的添加方法。 安装依赖 [代码]npm install jsonwebtoken npm install koa-jwt [代码] app.js 引用 [代码]const jwtKoa = require('koa-jwt'); [代码] 设置不需要JWT验证的目录或者文件 [代码]const secret = '设置密钥'; app.use(jwtKoa({secret}).unless({ path: ['/','\/favicon.ico',/^\demo/] })) [代码] 数组中的路径不需要通过jwt验证。 授权 小程序 wx.request 发送网络请求的 referer header 不可设置。 其格式固定为 https://servicewechat.com/{appid}/{version}/page-frame.html,其中 {appid} 为小程序的 appid,{version} 为小程序的版本号,版本号为 0 表示为开发版、体验版以及审核版本,版本号为 devtools 表示为开发者工具,其余为正式版本。 那么我们就可以根据 ctx.header 里的 referer 进行初步的限制,比如指定的 appid 才能生成令牌。 我们在生成令牌的时候可以把简单的信息加入进去,如: [代码]const userToken = { referer: refererArray[2], appid: refererArray[3], version: refererArray[4], data: '此处可传入用户的信息' } [代码] 生成令牌: [代码]const jwt = require('jsonwebtoken'); const secret = '设置密钥'; jwt.sign(userToken, secret, {expiresIn: '2h'}); [代码] expiresIn:为令牌的有效期 这样简单的JWT令牌就生成好了,再通过接口返回给小程序端。 小程序前端如何使用JWT? 很简单,在header里加入下面属性即可。 [代码]authorization: 'Bearer 获取到的令牌' [代码] JWT优点 可扩展性好 应用程序分布式部署的情况下,session需要做多机数据共享,通常可以存在数据库或者redis里面。而JWT不需要。 无状态 JWT不在服务端存储任何状态。RESTful API的原则之一是无状态,发出请求时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,这破坏了这一原则。另外JWT的载荷中可以存储一些常用信息,用于交换信息,有效地使用JWT,可以降低服务器查询数据库的次数。 JWT缺点 安全性 由于jwt的payload是使用base64编码的,并没有加密,因此jwt中不能存储敏感数据。而session的信息是存在服务端的,相对来说更安全。 性能 JWT太长。由于是无状态使用JWT,所有的数据都被放到JWT里,如果还要进行一些数据交换,那载荷会更大,经过编码之后导致jwt非常长,cookie的限制大小一般是4k,cookie很可能放不下,所以jwt一般放在local storage里面。并且用户在系统中的每一次http请求都会把jwt携带在Header里面,http请求的Header可能比Body还要大。而sessionId只是很短的一个字符串,因此使用JWT的http请求比使用session的开销大得多。 一次性 无状态是JWT的特点,但也导致了这个问题,JWT是一次性的。想修改里面的内容,就必须签发一个新的JWT。 (1)无法废弃 通过上面JWT的验证机制可以看出来,一旦签发一个 JWT,在到期之前就会始终有效,无法中途废弃。例如你在payload中存储了一些信息,当信息需要更新时,则重新签发一个JWT,但是由于旧的JWT还没过期,拿着这个旧的JWT依旧可以登录,那登录后服务端从JWT中拿到的信息就是过时的。为了解决这个问题,我们就需要在服务端部署额外的逻辑,例如设置一个黑名单,一旦签发了新的JWT,那么旧的就加入黑名单(比如存到redis里面),避免被再次使用。 (2)续签 如果你使用jwt做会话管理,传统的cookie续签方案一般都是框架自带的,session有效期30分钟,30分钟内如果有访问,有效期被刷新至30分钟。一样的道理,要改变JWT的有效时间,就要签发新的JWT。最简单的一种方式是每次请求刷新JWT,即每个http请求都返回一个新的JWT。这个方法不仅暴力不优雅,而且每次请求都要做JWT的加密解密,会带来性能问题。另一种方法是在redis中单独为每个JWT设置过期时间,每次访问时刷新JWT的过期时间。
2019-02-20