这周撸了两款小程序,分享一些经验(前后台)。
本周撸了两款小程序,在这里总结下开发过程中的小经验,希望对大家有用。 小程序端 我们先说小程序要注意的地方。 默认入口转发问题 当一个小程序Page的js文件中存在 onShareAppMessage 方法时,可以触发转发功能,但是通过小程序开发者工具生成的模板中,入口文件的js中并没有此方法,为了发布后方便对小程序进行分享,建议在pages/index/index.js中添加。 当然默认情况下,我们需要点击小程序右上角的...才能看到转发,这样并不能对用户起到引导作用,通常的做法是使用一个button,并且设置open-type为share,这样就可以通过按钮启动分享。 但是原生按钮很难看,我们可以设置一个图片,在wxml内的代码一般如下 [代码]<[代码][代码]button[代码] [代码]open-type[代码][代码]=[代码][代码]"share"[代码][代码]><[代码][代码]image[代码] [代码]src[代码][代码]=[代码][代码]"/images/icon-share.png"[代码][代码]></[代码][代码]image[代码][代码]></[代码][代码]button[代码][代码]>[代码] 当然需要通过wxss将button的样式去掉,背景、边框等等,代码如下 [代码]button {[代码] [代码] [代码][代码]padding[代码][代码]:[代码][代码]0[代码][代码];[代码] [代码] [代码][代码]margin[代码][代码]:[代码][代码]0[代码] [代码]auto[代码][代码];[代码] [代码] [代码][代码]width[代码][代码]:[代码][代码]70[代码][代码]rpx;[代码] [代码] [代码][代码]height[代码][代码]:[代码][代码]70[代码][代码]rpx;[代码] [代码] [代码][代码]display[代码][代码]:[代码][代码]block[代码][代码];[代码] [代码] [代码][代码]border[代码][代码]:[代码][代码]0[代码][代码];[代码] [代码] [代码][代码]background[代码][代码]: [代码][代码]transparent[代码][代码];[代码] [代码]}[代码] [代码]button::after {[代码] [代码] [代码][代码]border[代码][代码]:[代码][代码]0[代码][代码]; [代码] [代码]}[代码]尤其是对 button::after 要进行设置,否则按钮的边框是无法去掉的。 [图片] 关于登录 关于小程序登录逻辑都差不多,从小程序发一个请求(含code)给服务器代码,服务器通过code换取open_id和session_key,其中open_id我们需要存储,用来表示用户身份,session_key用来获取用户基本信息时解密使用。 当服务器端进行了存储后要生成一个key,将其返给小程序,以后小程序凡是发起需要用户认证的请求,都带这个key用来判断用户身份,在yii2中,这个key就是我们restful中的access_token。 以上是关于小程序登录的前后台逻辑,如果你使用yii2类框架,很多都内置了,并不复杂。 但是这里还有几个问题 1. 小程序端何时进行登录逻辑? 2. 发起请求时access_token过期了如何处理? 小程序端何时进行登录逻辑? 在登录判断上,我们先进行小程序是否含有access_token来判断,当然即便存在,还需要对checkSession进行一次判断。 [代码]var[代码] [代码]session = Session.get();[代码][代码]// 获取access_token[代码] [代码]if[代码] [代码](session) {[代码] [代码] [代码][代码]wx.checkSession({[代码] [代码] [代码][代码]success: [代码][代码]function[代码] [代码]() {[代码][代码] [代码] [代码] [代码][代码]},[代码] [代码] [代码][代码]fail: [代码][代码]function[代码] [代码]() {[代码][代码] [代码] [代码] [代码][代码]doLogin();[代码] [代码] [代码][代码]},[代码] [代码] [代码][代码]});[代码] [代码]} [代码][代码]else[代码] [代码]{[代码] [代码] [代码][代码]doLogin();[代码] [代码]}[代码] 这里Session是对access_token的一次封装。 发起请求时access_token过期了如何处理? 这个问题最常发生的场景就是我们发送了一次需要用户认证的请求,此刻如果服务器端发现收到的access_token已经失效,会返回异常,此刻小程序一般要如何处理那? 我的推荐方式是静默状态的自动登录一次再,先看代码。 [代码]if[代码] [代码](response.statusCode === 401) {[代码] [代码] [代码][代码]Session.clear();[代码] [代码] [代码][代码]if[代码] [代码](!hasRetried) {[代码] [代码] [代码][代码]hasRetried = [代码][代码]true[代码][代码];[代码] [代码] [代码][代码]doRequestWithLogin();[代码][代码]// [代码] [代码] [代码][代码]return[代码][代码];[代码] [代码] [代码][代码]}[代码] [代码]}[代码] 我来解释一下这段代码,当小程序发起一次需要用户认证的请求但是被服务器驳回为401错误(一般为用户认证失败),此刻我先清理掉小程序端自身对access_token(Session.clear()方法实现),然后在进行登录后再发起请求(doRequestWithLogin())。 但是我们不能一直在执行请求失败就登录操作,因此可以设置一个开关hasRetried,只进行一次尝试。 客服消息 在小程序开发中,客服消息的重要性不言而喻,它除了作为客服服务外,还作为小程序到微信浏览器的一个渠道,比如本次在「宝宝爱识图」https://nai8.me/images/bao-say-qrcode.png 的开发中,我用它来实现将收款微信号到用户的推送工作,这主要是解决在ios端虚拟产品不能进行微信支付事情。 一般的策略是让客户点击客服按钮然后输入一个关键词,服务器端通过客服消息接口识别用户身份,结合关键词给予响应的消息推送。 [图片] 模板消息 很多人认为很鸡肋的方法,毕竟需要获取form_id和prepay_id后才能下发模板消息,似乎很受限制,但是我们可以建立一个formId的种子表,将尽可能多的用户和后台的行为都采用form表单提交的形式,并且获取formID,对,要变态的多,这样你的formId表数据起来了,以后想发消息的时候用就好了。 关于如何设置能获取formId的小程序表单也很简单,设置report-submit为真即可,如下代码 [代码]<[代码][代码]form[代码] [代码]bindsubmit[代码][代码]=[代码][代码]"abc"[代码] [代码]report-submit[代码][代码]=[代码][代码]"{{true}}"[代码][代码]></[代码][代码]form[代码][代码]>[代码] 然后在js端通过如下代码获取 [代码]abc(event) {[代码][代码] [代码][代码]var[代码] [代码]formId = event.detail.formId;[代码][代码] [代码][代码]xxx[代码][代码]},[代码] 尽可能多的。 服务器端 接下来总结下服务器端,我使用yii2的restful组件作为接口支持,关于restful的基本功能请参考yii2官方文档或我之前录制的课程《Yii2的RESTful讲解》https://nai8.me/book/view.html?id=13 ,在这里分享我认为关键的点。 让yii2能解析json的请求内容 默认情况下yii2并不能识别请求中的json格式,而我们小程序在发起请求时喜欢用它,因此我们要对yii2进行一下配置。 config/web.php [代码]'request'[代码] [代码]=> [[代码][代码] [代码][代码]'cookieValidationKey'[代码] [代码]=> [代码][代码]'xxx'[代码][代码],[代码][代码] [代码][代码]'parsers'[代码] [代码]=> [[代码][代码] [代码][代码]'application/json'[代码] [代码]=> [代码][代码]'yii\web\JsonParser'[代码][代码],[代码][代码] [代码][代码]],[代码][代码]],[代码] 对,在web.php中对组件request增加内容解析yii\web\JsonParser。 用户认证 小程序的登录需要服务端的**用户认证**配合,当然我使用yii2框架,内置的restful已经支持了,如果你的系统不支持用户认证,可以自行建立access_token的生成机制,具体可以参考腾讯开放的小程序服务端框架wafer。 在yii2的restful中的用户认证使用了行为机制,我们来看下流程代码 [代码]// 在需要授权的控制器内[代码][代码]class[代码] [代码]CardController [代码][代码]extends[代码] [代码]ActiveController {[代码] [代码] [代码][代码]public[代码] [代码]$modelClass[代码] [代码]= [代码][代码]'app\modules\say\models\Card'[代码][代码];[代码] [代码] [代码][代码]public[代码] [代码]function[代码] [代码]behaviors() {[代码][代码] [代码][代码]$behaviors[代码] [代码]= parent::behaviors();[代码][代码] [代码][代码]$behaviors[代码][代码][[代码][代码]'authenticator'[代码][代码]] = [[代码][代码] [代码][代码]'class'[代码][代码]=>HttpBearerAuth::className(),[代码][代码] [代码][代码]'only'[代码][代码]=>[[代码][代码] [代码][代码]'index'[代码][代码] [代码][代码]],[代码][代码] [代码][代码]];[代码][代码] [代码][代码]return[代码] [代码]$behaviors[代码][代码];[代码][代码] [代码][代码]}[代码][代码] [代码][代码]...[代码][代码]}[代码] 就如上面的代码,我们生命index动作是需要用户认证的,并且认证机制为HttpBearerAuth类型 https://nai8.me/video/detail.html?id=175 ,在小程序端需要在header内包含如下代码 [代码]header: {[代码][代码] [代码][代码]'Authorization'[代码][代码]: [代码][代码]'Bearer '[代码] [代码]+ access_token[代码][代码]},[代码] 当服务器验证通过后,在action的代码内直接使用 Yii::$app->user->id 就可以获得用户ID。 ok~ 这就是前几天小程序开发过程中给大家分析的点,后续升级过程中会继续分享给大家。