使用钉钉的扫码会出现多个回调(DTFrameLogin)

24 篇文章 0 订阅

官方:地址

出现的问题

1692861955468

解决后效果

1692861665687

正常使用(按照官网的流程进行使用)

fn.js
该文件就是钉钉官网的js文件,我下载到了本地
js文件下载地址

!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1382)}({1382:function(e,t){var r=function(e,t){var r=e.match(new RegExp("[?&]"+t+"=([^&]+)"));return r?r[1]:null};window.DTFrameLogin=function(e,t,n,o){var i,u=e.id&&document.getElementById(e.id)||null,c=document.createElement("iframe");t.client_id&&t.redirect_uri&&t.response_type&&t.scope?u?(u.innerHTML="",u.appendChild(c),c&&c.contentWindow&&c.contentWindow.postMessage&&window.addEventListener?(c.src="https://"+((i=t).isPre?"pre-login":"login")+".dingtalk.com/oauth2/auth?iframe=true&redirect_uri="+i.redirect_uri+"&response_type="+i.response_type+"&client_id="+i.client_id+"&scope="+i.scope+(i.prompt?"&prompt="+i.prompt:"")+(i.state?"&state="+i.state:"")+(i.org_type?"&org_type="+i.org_type:"")+(i.corpId?"&corpId="+i.corpId:"")+(i.exclusiveLogin?"&exclusiveLogin="+i.exclusiveLogin:"")+(i.exclusiveCorpId?"&exclusiveCorpId="+i.exclusiveCorpId:""),c.width=""+(e.width||300),c.height=""+(e.height||300),c.frameBorder="0",c.scrolling="no",window.addEventListener("message",(function(e){var t=e.data,i=e.origin;if(/login\.dingtalk\.com/.test(i)&&t)if(t.success&&t.redirectUrl){var u=t.redirectUrl,c=r(u,"authCode")||"",d=r(u,"state")||"",s=r(u,"error")||"";c?n&&n({redirectUrl:u,authCode:c,state:d}):o&&o(s)}else o&&o(t.errorMsg)}))):o&&o("Browser not support")):o&&o("Element not found"):o&&o("Missing parameters")}}});

util.js
这个文件就是按照钉钉文档的流程编写的代码

//钉钉js文件地址
import './fn.js'
//跳转地址,需要在钉钉后台提前配置好,暂时未用到
const url = location.origin + '/#/'
export const BASE_URL = encodeURIComponent(url);
const appid_default = 'xxxxxx' //填写自己的钉钉应用id
const state_default = 'PC'

const fn = () => {
    console.log('默认的回调');
}

//INIT_DINDING 生成钉钉二维码 传递两个参数
//参数一,html标签id,该标签用来渲染二维码
//参数二,回调,在扫码完成后,进行的操作
export const INIT_DINDING = (id = "qr_code_div", callback = fn) => {

    const demo = new window.DTFrameLogin(
        {
            id,
            width: 300,//二维码宽度
            height: 300,//二维码高度
        },
        {
            client_id: appid_default,
            redirect_uri: BASE_URL,
            client_id: appid_default,
            scope: 'openid',
            response_type: 'code',
            state: state_default,
            prompt: 'consent',

        },
        (loginResult) => {
            // const { redirectUrl, authCode, state } = loginResult;
            //loginResult字段说明____________________________
            //redirectUrl  重定向的地址
            //authCode     !!!很重要,这个就是钉钉返回的唯一标识
            //state        我上面写的PC,因此这个值就是PC,用来以后区别pc和app
            
            // 这里可以直接进行重定向
            // window.location.href = redirectUrl;
            // 也可以在不跳转页面的情况下,使用code进行授权
            
            //——————————————触发回调————————————————————————————————————
            callback && callback(loginResult)
            return
        },
    )
}

edit.vue
封装出现二维码的组件

<template>
  <div>
    <div class="qr_code_div" ref="qrCodeDiv" id="qr_code_div"></div>
  </div>
</template>
<script>
//看准你自己的文件地址---------------
import { INIT_DINDING, SET_MESSAGE } from "./util.js";
export default {
  data() {
    return {};
  },

  mounted() {
    INIT_DINDING("qr_code_div",function () {
      console.log("this__________________这是扫码的回调");
      // fn=null
    });
  },
  created() {},
  methods: {},
  beforeDestroy(){
  }
};
</script>
<style lang="scss" scoped>
.qr_code_div {
  width: 300px;
  height: 300px;
  margin: 0 auto;
}
</style>

app.vue
使用组件

<template>
  <div>
    <button @click='blg = !blg'>{{blg}}</button>
    <edit v-if="blg"></edit>
  </div>
</template>
<script>
import edit from './edit'
export default {
  data() {
    return {
      blg:true
    };
  },
  components:{
    edit
  },
  mounted() {

  },
  created() {},
  methods: {},
};
</script>
<style lang="scss" scoped>
</style>


按照上面的流程便可以正常的在h5使用钉钉的扫码组件了

修改后使用(解决方式)

解决组件关闭后,多次开启组件会产生多个回调的bug

在上方的edit.vue组件中进行修改

<template>
  <div>
    <div class="qr_code_div" ref="qrCodeDiv" id="qr_code_div"></div>
  </div>
</template>
<script>
import { INIT_DINDING, SET_MESSAGE } from "../utils/init";
//1、步骤一
//修改之前的匿名回调
let fn = function () {
  console.log("this__________________这是扫码的回调");
  //2、步骤二
  //回调执行后把函数置空
  fn = null;
};
export default {
  data() {
    return {};
  },

  mounted() {
    //3、步骤三,传递修改后的回调
    INIT_DINDING("qr_code_div", fn);
  },
  created() {},
  methods: {},
  beforeDestroy() {
    //4、步骤四---组件销毁也把函数置空
    fn = null;
  },
};
</script>
<style lang="scss" scoped>
.qr_code_div {
  width: 300px;
  height: 300px;
  margin: 0 auto;
}
</style>

自己的理解(路人可忽略该内容!)

查看钉钉的打包后的源码,发现是通过绑定message监听来接受回调的
其实还有另外一种,就是在message事件执行后,立即取消绑定,只让他执行一次
但是考虑到是匿名事件,并且是打包后的代码,并没有进行更改
就使用了另一种方法,也就是上诉的方法
钉钉源码

! function (e) {
    var t = {};

    function r(n) {
        if (t[n]) return t[n].exports;
        var o = t[n] = {
            i: n,
            l: !1,
            exports: {}
        };
        return e[n].call(o.exports, o, o.exports, r), o.l = !0, o.exports
    }
    r.m = e, r.c = t, r.d = function (e, t, n) {
        r.o(e, t) || Object.defineProperty(e, t, {
            enumerable: !0,
            get: n
        })
    }, r.r = function (e) {
        "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
            value: "Module"
        }), Object.defineProperty(e, "__esModule", {
            value: !0
        })
    }, r.t = function (e, t) {
        if (1 & t && (e = r(e)), 8 & t) return e;
        if (4 & t && "object" == typeof e && e && e.__esModule) return e;
        var n = Object.create(null);
        if (r.r(n), Object.defineProperty(n, "default", {
                enumerable: !0,
                value: e
            }), 2 & t && "string" != typeof e)
            for (var o in e) r.d(n, o, function (t) {
                return e[t]
            }.bind(null, o));
        return n
    }, r.n = function (e) {
        var t = e && e.__esModule ? function () {
            return e.default
        } : function () {
            return e
        };
        return r.d(t, "a", t), t
    }, r.o = function (e, t) {
        return Object.prototype.hasOwnProperty.call(e, t)
    }, r.p = "", r(r.s = 1382)
}({
    1382: function (e, t) {
        var r = function (e, t) {
            var r = e.match(new RegExp("[?&]" + t + "=([^&]+)"));
            return r ? r[1] : null
        };
        window.DTFrameLogin = function (e, t, n, o) {
            var i, u = e.id && document.getElementById(e.id) || null,
                c = document.createElement("iframe");
            t.client_id && t.redirect_uri && t.response_type && t.scope ? u ? (u.innerHTML = "", u.appendChild(c), c && c.contentWindow && c.contentWindow.postMessage && window.addEventListener ? (c.src = "https://" + ((i = t).isPre ? "pre-login" : "login") + ".dingtalk.com/oauth2/auth?iframe=true&redirect_uri=" + i.redirect_uri + "&response_type=" + i.response_type + "&client_id=" + i.client_id + "&scope=" + i.scope + (i.prompt ? "&prompt=" + i.prompt : "") + (i.state ? "&state=" + i.state : "") + (i.org_type ? "&org_type=" + i.org_type : "") + (i.corpId ? "&corpId=" + i.corpId : "") + (i.exclusiveLogin ? "&exclusiveLogin=" + i.exclusiveLogin : "") + (i.exclusiveCorpId ? "&exclusiveCorpId=" + i.exclusiveCorpId : ""), c.width = "" + (e.width || 300), c.height = "" + (e.height || 300), c.frameBorder = "0", c.scrolling = "no", window.addEventListener("message", (function (e) {
                var t = e.data,
                    i = e.origin;
                    //这里这里-------------------------------看上面👆
                if (/login\.dingtalk\.com/.test(i) && t)
                    if (t.success && t.redirectUrl) {
                        var u = t.redirectUrl,
                            c = r(u, "authCode") || "",
                            d = r(u, "state") || "",
                            s = r(u, "error") || "";
                        c ? n && n({
                            redirectUrl: u,
                            authCode: c,
                            state: d
                        }) : o && o(s)
                    } else o && o(t.errorMsg)
            }))) : o && o("Browser not support")) : o && o("Element not found") : o && o("Missing parameters")
        }
    }
});
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值