前端面试(6)公众号,小程序


大纲:
微信,小程序授权( openId,unid,用户信息,手机号)
微信支付(H5,公众号,小程序,app)
微信上传图片(H5,公众号,小程序)
支付宝支付(H5,app)

小程序

小程序中如何合并 seaData,减少 setData 次数:
** 合并`setdata`的请求,减少通讯的次数:**
避免过于频繁调用setData,应考虑将多次setData合并成一次setData调用

// 不要频繁调用setData
this.setData({ a: 1 });
this.setData({ b: 2 });
// 绝大多数时候可优化为
this.setData({ a: 1, b: 2 });

5. 列表的局部更新
在一个列表中,有n条数据,采用上拉加载更多的方式,假如这个时候想对其中某一个数据进行点赞操作,还能及时看到点赞的效果。

  • 可以采用setData全局刷新,点赞完成之后,重新获取数据,再次进行全局重新渲染,这样做的有点是:方便,快捷!缺点是:用户体验极其不好,当用户刷量 100 多条数据后,重新渲染会出现空白期。
  • 也可以采用局部刷新,将点赞的id传过去,知道点的是哪一条数据,重新获取数据,查找相对应id的那条数据的下标(index是不会改变的),用setData进行局部刷新,如此,便可以显著提升渲染速度。
this.setData({
    list[index]=newList[index]
})

公众号

微信登录几种方式:
微信联合登录和微信授权登录
微信联合登录;也就是我们常用的微信移动端/PC 端之间的扫码登录,PC 端用微信扫码登录,微信移动端确认授权登录后,应用可以从微信拿到用户的 open id 或 union id,将微信获取的用户信息与自己账户体系中的用户身份进行关联;

授权登录:需要用户确认登录,这样可以通过用户的个人确认,获取用户全面的信息,无论是否关注相关微信公众号等都可以获取。

静默授权不需要用户确认,只需要用户访问某个网页,属于嵌套在普通网页里的授权形式,但是只能获取到用户的唯一标示 openid 和 union id,无法拿到用户的微信头像、微信名称等个人信息,对于用户的简单认证还是很有用的。

如何通过微信账户体系来做多应用、多平台之间的账户互通体系;如果某个服务同时分布在多个公众号中,账户体系如何建立;如何做到用户身份唯一识别;
1)、同一用户不同公众号/应用下 open id 不同,同一用户不同公众号/应用下 unionid 相同;
2)、建立应用账户体系时,通过 union 来进行多应用/平台之间的用户账户体系识别与合并;
3)、多应用/平台建立账户体系时,需要做到唯一 user id 对应唯一 union id;
某个服务,包括移动 app 端、PC 网页端、公众号端服务,那么用户使用微信授权登录的数据流转流程是怎么样的;
1、用户通过微信授权移动 app 服务;该应用服务即可通过接口获取用户的 union id,这个时候,如果在数据库中没有查到该 id,则识别为新用户,直接创建一个 user id,该唯一 user id 与 union id 对应;
2、用户通过微信扫码 PC 端授权联合登陆获取 PC 端服务;该应用服务即可通过接口获取用户的 union id,这个时候,在数据库中查到有这个 id,就会把 pc 登录这个账户合并到之前创建的唯一 user id 账户下;
3、用户通过关注该服务公众号,用微信授权登录公众号服务;该应用服即可通过接口获取用户的 union id,这个时候,在数据库中查到有这个 id,就会把公众号中登录的这个账户合并到之前创建的唯一 user id 账户下;

网页授权的两种 scope 的区别说明:
1、授权登录以 snsapi_base 为 scope 发起的网页授权,是用来获取进入页面的用户的 openid 的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)特点:用户无感知;
2、静默授权以 snsapi_userinfo 为 scope 发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
特殊场景下静默授权:
对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是 scope 为 snsapi_userinfo,也是静默授权,用户无感知。
网页授权流程:
1、引导用户进入授权页面同意授权,获取 code **
确保微信公众账号拥有授权作用域(scope 参数)的权限的前提下引导用户去授权页面
参考链接:
scope 为 snsapi_base
注意:appid,redirect_uri,state 这些要和后台协商好
https://open.weixin.qq.com/connect/oauth2/authorize?appid=”+wx_appid+”&redirect_uri=”+api.wx_reg+”&response_type=code&scope=snsapi_login,snsapi_userinfo&state=1,0#wechat_redirect
scope 为 snsapi_userinfo
https://open.weixin.qq.com/connect/oauth2/authorize?appid=”+wx_appid+”&redirect_uri=”+api.wx_reg+”&response_type=code&scope=snsapi_base,snsapi_userinfo&state=1,0#wechat_redirect


用户同意授权后
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
**2、通过 code 换取网页授权 access_token(后台操作)(之前是 php 中间做了一步中转操作通过 code 换取网页授权 access_token 这步是后台操作)

页面跳回跳的 url 上 redirect_uri/?code=CODE&state=STATE。code
通过 code 换取的是网页授权 access_token,如果网页授权的作用域为 snsapi_base,则本步骤中获取到网页授权 access_token 的同时,也获取到了 openid,snsapi_base 式的网页授权流程即到此为止。
3:需要个人信息。后台通过 code 得到值之后返回给前端去操作
2、通过 code 换取网页授权 access_token(前端操作)
window.location.href=”https://open.weixin.qq.com/connect/oauth2/authorize?appid="+wx_appid+"&redirect_uri="+encodeURIComponent(“+中转页面的html比如 location.html+”)+”&response_type=code&scope=snsapi_base,snsapi_userinfo&state=”+wx_rt_url_code(前端自己判断,存储,目的是确定授权页面来源。以方便授权后跳回的页面地址)+”,1(这值是和后台协商)#wechat_redirect”;
3:location.html 页面授权后会跳转到这个页面。同时在页面 url?后参数中拿到 code 和 state 的值 (state 就是上面传入的)
就可以拿着这两个参数去进行登录操作。获取相应的 token ,wxUserToken 等需要的信息 。根据 wx_rt_url_code 自己定义个规则回转到相应的页面。完成登录状态。进行下一步操作
为了确保参数的正确传入,state 可以进行 decodeURIComponent 下。(之前调接口的时候程序报错,发现 pc 端授权登录的时候微信解析是有逗号,手机端 state 是没逗号,确保程序的正常运行可以进行解码下)
网站的微信授权登录是以二维码的形式 api 网址 api https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN
手机端微信授权登录 api 网址 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=&lang=zh_CN

微信支付:

H5 支付(即在网页端(非微信浏览器)页面调用支付)

function onBridgeReady() {
  WeixinJSBridge.invoke(
    "getBrandWCPayRequest",
    {
      appId: "wx2421b1c4370ec43b", //公众号名称,由商户传入
      timeStamp: "1395712654", //时间戳,自1970年以来的秒数
      nonceStr: "e61463f8efa94090b1f366cccfbbb444", //随机串
      package: "prepay_id=u802345jgfjsdfgsdg888", //统一下单接口返回的prepay_id,提交格式如:prepay_id=***
      signType: "MD5", //签名类型,默认为MD5,支持HMAC-SHA256和MD5 注意此处需与统一下单的签名类型一致
      paySign: "70EA570631E4BB79628FBCA90534C63FF7FADD89", //微信签名 (算法生成)
    },
    function (res) {
      if (res.err_msg == "get_brand_wcpay_request:ok") {
        // 使用以上方式判断前端返回,微信团队郑重提示:
        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      }
    }
  );
}
if (typeof WeixinJSBridge == "undefined") {
  if (document.addEventListener) {
    document.addEventListener("WeixinJSBridgeReady", onBridgeReady, false);
  } else if (document.attachEvent) {
    document.attachEvent("WeixinJSBridgeReady", onBridgeReady);
    document.attachEvent("onWeixinJSBridgeReady", onBridgeReady);
  }
} else {
  onBridgeReady();
}

开微信开发者工具,打 log,最后发现在这一步时候 if (typeof WeixinJSBridge == “undefined”)
1.ios 能够调起微信浏览器的 js-sdk 2.安卓大部分都走到 undefined 里面去了
这里其实我也不太清楚原因。个人感觉是微信安卓的内置浏览器版本和这个 WeixinJSBridge 方法的问题。(希望有大神能够解答一下)

getConfig(){
            wx.config({
                debug: this.wx_config.debug, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: this.wx_config.appId, // 必填,公众号的唯一标识
                timestamp: this.wx_config.timestamp, // 必填,生成签名的时间戳
                nonceStr: this.wx_config.nonceStr, // 必填,生成签名的随机串
                signature:this.wx_config.signature,// 必填,签名
                jsApiList: this.wx_config.jsApiList // 必填,需要使用的JS接口列表
            });
            //微信支付
            wx.ready(function() {
                  // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
                // console.log(this.jsApiCall());
                wx.chooseWXPay({
                    timestamp: this.wechat_code.timestamp,
                    nonceStr:this.wechat_code.nonceStr,
                    package: this.wechat_code.package,
                    signType: this.wechat_code.signType,
                    paySign: this.wechat_code.paySign,
                    success: function () {
                        // 支付成功后的回调函数
                        alert("支付成功");
                        window.location.href = "/hd/becomevip";
                    },
                    cancel: function() {
                        alert("支付失败");
                    }
                });
            }.bind(this));
        },

分析和总结
** *
扫码支付、公众号支付、H5 支付、小程序支付都有一个同步回调地址跟异步通知地址,只是设置方式有所区别 :
1. 扫码支付
同步回调地址在微信商户平台中设置,异步通知地址在统一下单接口的请求参数中设置;
2. 公众号支付
同步回调地址在 JSAPI 发起支付的回到函数中进行回到,异步通知地址在统一下单接口的请求参数中设置;
3. H5 支付
同步回调地址:在统一下单接口的返回参数中有一个参数 mweb_url,在 mweb_url 中以 get 传参形式新增一个参数 redirect_url,redirect_url 即是同步回调函数;
异步通知地址:统一下单接口的请求参数中设置;
*4. 小程序支付\\

同步回调地址:在小程序获得支付参数,并通过 js 调起微信支付以后,js 中会有一个回调函数,同步回调地址在该回调函数中添加;
异步通知地址:统一下单接口的请求参数中设置。

其中扫码支付主要用于电脑端;公众号支付跟 H5 支付主要用于移动端,因此商户在移动端使用微信支付的时候需要判断当前打开的浏览器是否是微信浏览器,并根据结果决定选择公众号支付或 H5 支付;小程序支付的话主要用于小程序内部,因此比如获取 openid,调用统一下单接口等操作均在给小程序提供数据接口服务的接口后台实现。

同步回调地址是作为微信后台跟商户进行页面跳转的渠道,因此同步回调地址是至关重要的,如果不填写,则可能导致支付完成后无法做页面跳转。
异步通知地址是微信后台对商户后台在完成微信支付后进行通知的重要通道,商户后台的异步通知地址必须是可访问的,在接收到微信的通知后,要做相关业务处理,并最终返回 SUCCESS 或 FAIL 的标识给微信,以告知微信不要在发送通知。

结尾
这里只是针对微信扫码支付、公众号支付、H5 支付、小程序支付等微信的四中支付方式做了一个大概的分析和总结,具体的每一个支付方式的接入方法还请以微信支付开发文档为重要参考;因篇幅有限,代码量大,这里就不贴具体的实现代码了。


文章作者:   leader755
版权声明:   本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 leader755 !
评论
 上一篇
前端面试(8)拷贝 前端面试(8)拷贝
js 的基本数据类型的赋值,就是值传递。引用类型对象的赋值是将对象地址的引用赋值。这时候修改对象中的属性或者值,会导致所有引用这个对象的值改变。如果想要真的复制一个新的对象,而不是复制对象的引用,就要用到对象的深拷贝。 数据类型(基本数据类
2020-08-27
下一篇 
前端面试(5)http,https 前端面试(5)http,https
http 状态码http 状态码是表示服务器对请求的响应状态,主要分为以下几个部分1:这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。2:表示请求成功,3:表示重定向4:表示客户端错误5**:表示服务器端错误100(c
2020-08-23
  目录