微信登录获取扫码结果的原理

之前面试,有个面试官问我微信扫码登录的原理,当时我没具体的看过,就说了一下自己的猜想。

用户访问网页版登录界面,登录页面动态生成一个登录链接,应该带有token之类的,这时候网页开始不停的给服务器发送请求,轮训用户是否已经扫码成功。用户用微信客户端扫码,扫码之后微信客户端向服务器发送一个请求,告诉服务器用户扫码成功,此时可以update一个标志,在网页版微信下次轮询登录状态时,获取到扫码成功的命令。

当时我是这么回答的,然后面试官问我,网页端怎么去轮询呢,我就说了用ajax去请求,设定一个超时时间,如果在指定时间内未获取扫码结果,超时返回。然后面试官说不对,说我肯定用过。当时我就开始想,还有更牛逼的技术么。回来就看微信的网页版js代码。摘录在下面了。

这里写图片描述
从浏览器数据包上看,微信网页版会每隔27秒就会发送一个登录扫码的请求。具体的js代码在https://res.wx.qq.com/zh_CN/htmledition/v2/js/webwxApp2e4e03.js 这个js文件中,下面摘除部分主要代码。

function a(i) {
                switch (i.code) {
                case 200:
                    t.newLoginPage(i.redirect_uri).then(function(t) {
                        var r = t.match(/<ret>(.*)<\/ret>/),
                        a = t.match(/<script>(.*)<\/script>/),
                        i = t.match(/<skey>(.*)<\/skey>/),
                        c = t.match(/<wxsid>(.*)<\/wxsid>/),
                        s = t.match(/<wxuin>(.*)<\/wxuin>/),
                        l = t.match(/<pass_ticket>(.*)<\/pass_ticket>/),
                        u = t.match(/<redirecturl>(.*)<\/redirecturl>/);
                        return u ? void(window.location.href = u[1]) : (e.$emit("newLoginPage", {
                            Ret: r && r[1],
                            SKey: i && i[1],
                            Sid: c && c[1],
                            Uin: s && s[1],
                            Passticket: l && l[1],
                            Code: a
                        }), void(o.getCookie("webwx_data_ticket") || n.report(n.ReportType.cookieError, {
                            text: "webwx_data_ticket 票据丢失",
                            cookie: document.cookie
                        })))
                    });
                    break;
                case 201:
                    e.isScan = !0,
                    n.report(n.ReportType.timing, {
                        timing: {
                            scan: Date.now()
                        }
                    }),
                    t.checkLogin(r).then(a);
                    break;
                case 408:
                    t.checkLogin(r).then(a);
                    break;
                case 400:
                case 500:
                case 0:
                    document.location.reload()
                }
                e.code = i.code,
                e.userAvatar = i.userAvatar,
                o.log("get code", i.code)
            }

case 块,通过判断不同的返回码,做出不同的操作,200 代表扫码成功,408代表未扫码,继续检查。下面是checkLogin(r) 的代码

		checkLogin: function(e, o) {
	           var n = t.defer(),
                o = o || 0;
                return window.code = 0,
                $.ajax({
                  url: r.API_login + "?loginicon=true&uuid=" + e + "&tip=" + o + "&r=" + ~new Date,
                  dataType: "script",
                  timeout: 35e3
                }).done(function() {
                    if (new RegExp("/" + location.host + "/"), window.redirect_uri && window.redirect_uri.indexOf("/" + location.host + "/") < 0) return void(location.href = window.redirect_uri);
                    var e = {
                        code: window.code,
                        redirect_uri: window.redirect_uri,
                        userAvatar: window.userAvatar
                    };
                    n.resolve(e)
                }),
                n.promise
            }

我对前端不是很了解,难道这不是ajax长链接请求,超时重新请求的意思么?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值