微信小程序服务端踩坑记录,不定期更新中

微信小程序踩坑记录,不定期更新中

Alt pic

【超硬小广告,大家可以关注一下我们美学福利社的小程序,我们会不定期推出明星单品试用。免费的噢。】

目前网易美学上线美学福利社小程序,是一个单独的消费工程。由于小程序是在微信容器中运行,诸多特性和API需要遵循微信的规范和标准。虽然微信正在不断努力地开放功能,完善标准,然而就现阶段而言,一些没有在文档中提到的要点仍然困扰着开发者。
本次微信小程序的开发,是一个痛苦的踩坑、摸索、完善的过程。现在把一些开发过程中遇到的注意点记录下来,希望能帮助到遇到同样问题的朋友们。

参考文档

  1. 小程序官方文档:https://mp.weixin.qq.com/debug/wxadoc/dev/index.html
  2. 微信公众平台开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

openid & unionid

openid和unionid都作为微信用户身份凭证,可以用于区分用户。但是,在早些时候App端接入OAuth2做三方登录时,由于Android和iOS的openid不一致,导致两个操作系统的用户无法判别。所以需要识别用户身份或者要求唯一性的情况下,请使用unionid。
并且,在OAuth2拿到的openid和在小程序中拿到的openid会不一致,在发送模板消息的时候需要填入openid做参数,请使用小程序中的openid。
官方解释如下:

Alt pic

wx.getUserInfo(OBJECT)

前端获取用户信息的接口,如下官方所示

Alt pic

当用户是新微信并且没有关注过小程序关联的公众号or服务号时,该方法获取到的openid可能为null。
比较保险地获取openid和unionid的方法应该是拿到encryptedData,用iv做解密,然后反序列化拿到openid。
官方文档如下:


Alt pic

Alt pic

官方的解密demo示例宣称覆盖多种主流服务端开发语言,但是并没有提供Java版本,果然是有程序语言鄙视链存在。PHP是世界上最好的语言。


Alt pic

Java解密主要代码如下:


public class AESUtils {
    public static boolean initialized = false;
    /**
     * AES解密
     * @param content 密文
     * @return
     */
    public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws Exception {
        initialize();
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public static void initialize(){
        if (initialized) return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}


Cookies

微信小程序不支持Cookie,但是支持request、response header,所以可以借用header来模拟Cookie机制。
response中设置“Set-Cookie”的header,request中再带上“Cookie”,再手动做解析、过期时间来处理就可以了。
虽然功能能实现,但是毕竟有些繁琐。


Template Message

模板消息,就是在微信用户关注了对应的服务号后,微信的会话列表会出现一个服务消息的会话栏,里面可以保存开发者向用户推送的消息。
下面是官方描述:

基于微信的通知渠道,我们为开发者提供了可以高效触达用户的模板消息能力,以便实现服务的闭环并提供更佳的体验。

模板推送位置:服务通知

模板下发条件:用户本人在微信体系内与页面有交互行为后触发,详见下发条件说明

模板跳转能力:点击查看详情仅能跳转下发模板的该帐号的各个页面

要想发送模板消息,首先得有模板。
创建模板的方式有两种
一种是人工在微信公众平台填写信息创建模板。
第二种是通过开发API去创建。

创建好模板后,准备发送模板消息。
首先要获取access_token,作为小程序全局唯一接口调用凭证,有效期2个小时。


Alt pic

简单存redis中。

    @Override
    public String getWxaAccessToken() throws Exception {
        String key = "access_token";
        String access_token = redisService.get(key);

        if (StringUtils.isEmpty(access_token)) {
            WXAccessTokenRequest request = new WXAccessTokenRequest();
            WXAccessTokenResponse response = request.sendRequest();
            if (StringUtils.isNotEmpty(response.getAccess_token())) {
                redisService.setWithExpireTime(key, response.getAccess_token(), response.getExpires_in());
            }

            access_token = response.getAccess_token();
        }
        return access_token;

    }

然后向微信的服务器POST一条请求就可以发送模板消息。

Alt pic

有一些参数需要说明一下。

  1. 如果你调试模板消息发现虽然收到模板消息,但是数据是空的,那么请检查你的data参数是一个JSONObject而不是一个String。
  2. form_id是由用户本人在微信体系内与页面有交互行为后触发,具体到代码中,是前端使用<form>组件,在formSubmit函数中获取form_id。form_id和openid是多对一的关系。只有由openid和小程序交互产生的form_id才能用于发送模板消息。
  3. form_id据微信的说法,有效期大概是7天,微信不保证。

看到这里,微信的想法应该是在于小程序交互时给用户发送提醒,微信并不希望模板消息用在主动给用户推送消息造成打扰。

那么,假如策划的需求是,在其他的运营后台系统(非微信)点击按钮(比如抽奖通知)想要通知用户,达到一个主动push的功能,该如何完成呢?
我们利用form_id有效期7天,可以做一些事情。我们把前端大部分的组件都包装成<form>,用户每次点击,收集一个openid、form_id的mapper,存入redis中,并将openid存入用户数据库。在运营想给用户推送一些数据时,查到所有的openid,顺便找到form_id,然后从form_id中找到一个最老的并且没有过期的id,发送模板消息并移出redis。

Alt pic

Java部分代码如下:

    @Override
    public ControllerResult<Void> gatherFormId(String form_id, long currentTime, String openid) {
        LOGGER.info("WXATokenFacadeImpl#gatherFormId: {} openid : {}", form_id, openid);

        if (StringUtils.isEmpty(openid)) {

            return ControllerResult.fail(BeautyCode.SYS_ERROR, "openid为空,自动舍弃form_id");

        }

        String key = RedisKeyGenerator.keyForOpenIdFormIdMapper(openid);

        redisService.zadd(key, Double.valueOf(currentTime), form_id);

        return ControllerResult.ok(null);
    }

    @Override
    public String findOldestFormIdAndRemove(String openid) {
        if (StringUtils.isEmpty(openid)) {
            LOGGER.info("WXATokenFacadeImpl#findOldestFormIdAndRemove:openid : {}", openid);
            return null;
        }

        long currentTime = System.currentTimeMillis();
        long lastestTime = currentTime - EXPIRE_TIME_MS - 1;// 比这个时间大才有效

        String key = RedisKeyGenerator.keyForOpenIdFormIdMapper(openid);

        redisService.zremrangebyscore(key, 0, lastestTime);

        List<String> formIds = redisService.zrangebyscore(key, lastestTime, currentTime, 0, 1);
        if (CollectionUtils.isNotEmpty(formIds)) {
            String formId = formIds.get(0);

            // 删除formid
            if (StringUtils.isNotEmpty(formId)) {
                redisService.zrem(key, formId);
            }

            return formId;
        }

        return null;
    }

本文不定期更新~

超硬小广告:最后欢迎大家关注“美学福利社”,有很多好用的明星单品可以免费申领试用噢!!


Alt pic
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 给提问的开发者的建议:提问之前先查询 文档、通过社区右上角搜索搜索已经存在的问题。 写一个简明扼要的标题,并且...
    极乐叔阅读 13,395评论 0 3
  • 美好不应该是虚妄 2017-11-10 笃行的猪 1399 删除了前面几篇,矛盾半晌。如何消除心里面不踏实的感觉,...
    笃行的猪阅读 276评论 0 0
  • 今天上午,我哭着喊着要吃寿司妈妈说:“不行,中午再吃。” 终于到了中午我们就一起先做寿司。我们还分了任务呢!妈...
    欧阳至俊阅读 81评论 0 0
  • 我们生活在一个高节奏的时代,连读书都要讲究“快餐”与“效率”,很多人可能一听到《红楼梦》这个书名就觉得这本书是自己...
    六个太阳金阅读 1,039评论 3 8