在实现微信扫码登录功能时,通常会遇到以下需求: 1. 用户扫码成功后需要自动关闭登录窗口 2. 主窗口需要刷新以更新登录状态 3. 整个过程需要流畅无闪烁
// 在登录窗口(子窗口)中的代码
function onLoginSuccess() {
if (window.opener && !window.opener.closed) {
// 通知父窗口刷新
window.opener.postMessage('WX_LOGIN_SUCCESS', window.location.origin);
// 关闭当前窗口
window.close();
}
}
// 在主窗口(父窗口)中的代码
window.addEventListener('message', function(event) {
if (event.data === 'WX_LOGIN_SUCCESS' && event.origin === '你的域名') {
window.location.reload(); // 刷新页面
}
});
// 在登录窗口(子窗口)中的代码
function onLoginSuccess() {
localStorage.setItem('wx_login_refresh', 'true');
window.close();
}
// 在主窗口(父窗口)中的代码
window.addEventListener('storage', function(event) {
if (event.key === 'wx_login_refresh' && event.newValue === 'true') {
localStorage.removeItem('wx_login_refresh');
window.location.reload();
}
});
// 主窗口代码
let loginWindow = null;
function openLoginWindow() {
loginWindow = window.open('login.html', '_blank', 'width=500,height=600');
// 轮询检查子窗口是否关闭
const checkInterval = setInterval(() => {
if (loginWindow.closed) {
clearInterval(checkInterval);
window.location.reload();
}
}, 500);
}
推荐使用方案一:window.opener + postMessage
是最优雅的解决方案,兼容现代浏览器且安全性好
注意事项:
完整示例代码:
// 主窗口代码
function openWechatLogin() {
const loginWindow = window.open(
'/wechat-login',
'wechatLogin',
'width=500,height=600,top=100,left=100'
);
// 添加消息监听
const messageHandler = function(event) {
if (event.data === 'WX_LOGIN_SUCCESS' && event.origin === window.location.origin) {
window.removeEventListener('message', messageHandler);
window.location.reload();
}
};
window.addEventListener('message', messageHandler);
// 超时处理
setTimeout(() => {
if (loginWindow && !loginWindow.closed) {
loginWindow.close();
}
}, 300000); // 5分钟超时
}
// 登录窗口代码(扫码成功后调用)
function handleLoginSuccess() {
if (window.opener && !window.opener.closed) {
window.opener.postMessage('WX_LOGIN_SUCCESS', window.location.origin);
}
window.close();
}
以上方案可根据您的具体技术栈和需求进行调整。