钉钉扫码登录(DTFrameLogin) 用户注销后重新登录出现回调叠加的问题

dd-login.js源码

javascript 复制代码
! 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")
		}
	}
});

在源码中注册了 window.addEventListener("message",fn)事件但是没有 在适当的时候注销掉该事件可能会出现回调函数多次执行的问题。

一般的话可以使用具名函数,或者在页面卸载的时候取消监听器。

javascript 复制代码
window.addEventListener("beforeunload", function() {
  window.removeEventListener("message", messageHandler);
});

下面是钉钉扫码多次回调的解决方案

javascript 复制代码
// 业务代码登录的回调函数
let doLoginByDD = (authCode: string) => {
  // 这里可以直接进行重定向
  // window.location.href = redirectUrl;
  // 也可以在不跳转页面的情况下,使用code进行授权
  useUserStoreHook()
    .loginBydingdingScan({
      code: authCode
    })
    .then(r => {
      if (r.code === 200) {
        // 获取后端路由
        initRouter().then(() => {
          router.push(getTopMenu(true).path);
          message("登录成功", { type: "success" });
          doLoginByDD = null;//登录成功后清空函数
        });
      }
    });
};
const ddLoginInit = () => {
  (window as any).DTFrameLogin(
    {
      id: "dingdingLoginFrame",
      width: 300,
      height: 300
    },
    {
      redirect_uri: encodeURIComponent(VITE_DINGDING_REDIRECT_URI),
      client_id: "你的钉钉ClienId",
      scope: "openid",
      response_type: "code",
      state: "xxxxxxxxx",
      prompt: "consent"
    },
    loginResult => {
      const { redirectUrl, authCode, state } = loginResult;
       // 这个回调下,用户登录成功后,退出,再次重新登录,会出现回调叠加。
      if (doLoginByDD) {
        doLoginByDD(authCode);
      }
    },
    errorMsg => {
      // 这里一般需要展示登录失败的具体原因,可以使用toast等轻提示
      console.error(`errorMsg of errorCbk: ${errorMsg}`);
    }
  );
//页面卸载 清空掉回调函数
onBeforeUnmount(() => {
  doLoginByDD = null;
});
相关推荐
shoubepatien1 分钟前
JavaWeb_Web基础
java·开发语言·前端·数据库·intellij-idea
WordPress学习笔记9 分钟前
wordpress外贸主题Google地图添加(替换)方案
前端·wordpress·wordpress地图
OrangeForce18 分钟前
Monknow新标签页数据导出
javascript·edge浏览器
小妖66634 分钟前
力扣(LeetCode)- 93. 复原 IP 地址(JavaScript)
javascript·tcp/ip·leetcode
码农秋1 小时前
Element Plus DatePicker 日期少一天问题:时区解析陷阱与解决方案
前端·vue.js·elementui·dayjs
未来之窗软件服务1 小时前
未来之窗昭和仙君(五十六)页面_预览模式——东方仙盟筑基期
前端·仙盟创梦ide·东方仙盟·昭和仙君·东方仙盟架构
top_designer1 小时前
Illustrato:钢笔工具“退休”了?Text to Vector 零基础矢量生成流
前端·ui·aigc·交互·ux·设计师·平面设计
星哥说事1 小时前
星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!
前端
donecoding1 小时前
前端AI开发:为什么选择SSE,它与分块传输编码有何不同?axios能处理SSE吗?
前端·人工智能
安_1 小时前
<style scoped>跟<style>有什么区别
前端·vue