在微信小程序正式发布之前,江湖上就早已充斥着它的传说,有说颠覆生态啦,有说开发者的春天来啦,有说还待观望啦。先不管那些虚的,出于技术上的兴趣,最近略微研究了一下,这才明白网上到处所谓“入坑指南”的文章真不是标题党,仅仅弄了个超级简单的玩意儿,一路上果然处处是坑,步步泣血。
单从前端开发角度讲,小程序还是比较容易上手的,而且结构、代码都比传统前端更加简洁,坑的是基础架构,也就是一个能够让你专心开发前端的整体环境,此番就来做个大致总结,以防再次掉坑。
第 1 坑:登录与Session
平常我们登录,无非是用户名密码一输,和后台数据库一校验,撑死再加个散列算法,哦了!小程序采用微信账号登录,过程则要复杂得多,一张流程图就直接把人干懵圈。
细细品味后发现,有些步骤是可以省略、或不完全按文档建议做的(虽然这可能引发安全风险,但不管了,我不用那么安全),只要获取到OpenID(微信账号)一切都好说,剩下的无非和传统开发一样,在第三方服务保存Session而已。
紧接着要获取用户信息,原本是一条龙服务,用户名密码校验完捎带就取出来了,小程序得单独调用接口getUserInfo,Get到之后又要对结果进行解密,一看解密算法再次懵圈。
好在返回结果中有些数据不解密也行,也够用,照样保存,照样运行。但你知道,在某些无聊的时候,会实在好奇加密数据究竟是些什么鬼,于是忍不住折腾一番,费了九牛二虎之力用文档中提供的示例代码解开了,我勒个去,和明文数据一毛一样啊,无非多了个OpenID和AppID,这些我早就有啊!亲!
一切就绪,没事走两步……What the hell,走不了两步,第二次请求居然不认第一次登录的Session,相当于每次请求都要重新登录,搞毛线!问了度娘,发现了一个叫PHPSESSID的东东,躲在客户端请求的Header里,小程序的SessionID和第三方服务器的SessionID不一致所以不认,调整登录逻辑,将服务器登录后产生的SessionID回传给小程序,第二次请求时在Header中捎上,搞定。
同时,好奇害死猫,我又想知道扫描二维码登录是肿么回事,便掉进一个更大的坑。首先需要网页端生成一个带参数(假设叫Ticket)的二维码(这个二维码指向小程序的某个处理页面),然后发起长轮询或长连接不断检测是否被扫描登录,出于安全考虑还要每隔一段时间换一个二维码;其次,用户扫描后进入小程序的处理页面(可以增加确认操作也可以不要),处理逻辑是带上OpenID和Ticket向服务器请求登录,服务器一看Ticket没错就绑定OpenID写入Session。
那么问题来了,怎么绑?文档中提到的Redis和Memcached是好东西,可以将数据绑定在内存,但是不会弄啊,貌似好复杂的样子;笨一点的办法就是用数据库绑定,但是效率低啊,而且无用数据不好删除。想来想去,还是用Session,系统自动回收省时省心,但新问题又来了,长轮询的时候其他程序根本跑不动,极其的慢。又问度娘,才知道Session文件是带锁的,一个程序读写Session时其他程序要等,平时不觉得,你轮着番读写那还不锁死?解决办法:Session Commit,即每次读写完毕后提交(或叫关闭)Session文件,Done!
第 2 坑:HTTPS和安全证书
正式发布的小程序向第三方服务器的请求必须使用https,也就是说第三方服务器必须支持https访问,我知道,安全第一,但安全是安全,也太特么折磨人了!这需要你对服务器有绝逼的控制权好吗,我没有啊,我用的是阿里云两年免费云虚拟主机,啥权限也不给哇,帮助中心还明确表示不支持https,花钱换服务器又舍不得,为了个“北半球最好用的邀约神器”至于下血本吗。
高手都在网上。有个哥们我和一样申请的两年免费主机,一样想搞个https出来(但不是用来做第三方请求),他的文章说这个免费套餐还附送一个CDN加速,通过CDN加速可以实现https。好,在纷繁芜杂的阿里云控制台找到了这个深藏功名的CDN,看到了开启https选项,什么?要SSL证书?真是柳暗花明又一坑,这玩意只在网银支付时见过,亲自怎么搞?还得靠度娘,度娘说证书需要到有签发资格的公司去申请,有好多种,如DV、IV、OV、EV,除了第一种(域名型)其他都要钱,我不知道具体有什么区别,反正第一种也能用。
和那哥们一样找了个叫StartCom的公司,云里雾里申请一通后发现要自己生成CSR文件,其中涉及公钥私钥密钥一大串懵逼钥匙,说实话这个原理完全不懂,总之参照说明还是一步步生成了,然后把文件里面的内容复制到CDN开启https所需的文本框,还要将域名解析到CDN提供的CNAME地址,其最终结果相当于域名指向CDN加速器,加速器再指向虚拟主机IP。
输入https网址试了试,确实可行;在小程序开发工具上点了点,也OK啊;满心欢喜拿起手机...What the F...完全没反应啊!继续找度娘吧,原来,苹果针对所有接入的APP都有个ATS(应用传输安全)要求,要求很多(有专门的在线检测工具),其中一项是“证书由Apple ATS信任的权威机构颁发”,网上传言StartCom被苹果封杀,虽然在其官网的信任机构列表中还能找到,但不深究了,换吧,经高人指点说可以向阿里云申请,其证书直接由Symantec公司颁发,据说是兼容性最好的,而且也有DV免费版,申请和生成证书的过程超乎寻常的简单,当初傻傻的跟着那哥们去StartCom,结果又掉他坑里了,真是坑中带坑。
第 3 坑:各种APIs
微信小程序本身内置了很多API(以wx.开头),是针对JS前端的,这些API稍微看看文档都问题不大,但开发过程中还会涉及很多需要https请求的API,问题就大了,其中有些还不好测试。
举个栗子,前面提到扫码登录时先要生成一个小程序带参页面的二维码,这个生成过程就要用到https请求API,其结果返回二维码图片的二进制流,显示这个图片时需要在前端页面设置Header的Content-Type为image/jpeg或png之类,否则就是乱码。问题是,一旦设置这样的Header,诺大一个页面就没法干别的了,只能显示这张二维码图片。想起以前做图片处理程序时用到Base64格式,是否可以转为Base64再设置在img src里呢,一试,果真可以。
再举个栗子,小程序可以有条件地向用户发送模板消息。首先要先到管理后台选择一个模板(光这个过程就很奇葩,直接发不好么),再调用指定的https API传入一大堆参数来发送消息,参数中有一个是申请的模板ID,还有一个叫FormID,就是点击发送消息的按钮所在的Form的ID,由小程序自动生成,在开发工具上生成的是Mock,Mock你妹啊,不能来点真格的么,明摆着不让测试啊!我忍了,弄到手机上测,可是明明能打印出FormID,API还是返回Invalid form id,百思不得其解,这回连度娘都无能为力……
继续各种折腾,尝试从小程序客户端发起请求,我的天,居然就可以了!换成服务器端发起,又不行了!见鬼,FormID一毛一样啊,心中之愤何止一万头草泥马奔腾而过……我甚至怀疑是不是只能由客户端发起,虽然这完全没道理,却还是试验了一下篡改Http请求的Refer地址来伪装客户端,果真没道理……又经过漫长的瞎搞,用尽洪荒之力,终于被我无意中(对,就是无意中)发现一个惊天大秘密——模板消息只能发送给操作者本人!!!把OpenID改为登录者就一切OK了,还Invalid form id,In你妹啊!发给本人还用你,我特么自己操作后自己不知道么,老子不玩了!
第 4 坑:未结束的结束语
磕磕绊绊走到现在,一个极其简单的微信小程序才算从坑里爬出来,前前后后耗费了近十天的宝贵光阴,当然中间还遇过无数小坑不堪回首,而真正要完成一个更为复杂庞大的程序,相信前方的路依旧坎坷,比如想想都觉得可怕的微信支付,以及仿原生APP交互设计的实现等等,我只能帮到这了,Good Luck!