You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让页面元素在异步用户凭证验证完成后再加载?

问题

我希望在网站任意页面加载前验证用户凭证,因此将包含异步函数(用于发起验证API调用)的脚本放置在HTML文档顶部,但发现当脚本执行异步操作时,页面其他元素仍会优先加载,即使脚本已放在顶部。相关代码如下:

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet">
    <link href="home.css" rel="stylesheet">
    <script src="../isUserLogged.js"></script> <!-- 这里是我提到的验证脚本 -->
    <script src="home.js" defer></script> <!-- 即使加了DEFER,这个脚本还是提前运行 -->
    <title>Caderneta</title>
</head>
<body>
    <div class="header">
        <p id="home-txt" class="header-txt">Home</p>
        <p id="user-txt" class="header-txt">Olá, Nome!</p>
    </div>
    <div class="content">
        <iframe src="../notebooks/notebooks.html"></iframe>
    </div>
</body>
</html>

isUserLogged.js代码

// Local Storage
const token = localStorage.getItem("token");

async function isUserSessionValid() {
    const options = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": token
        },
        body: token
    };
    try {
        const response = await fetch("http://localhost:8080/teachers/get-by-token", options);
        if(response.ok) {
            sessionStorage.setItem("user", JSON.stringify(await response.json()));
            return true;
        }
    } catch(e) {
    }
    alert("Erro ao validar sessão, faça login ou tente novamente mais tarde.");
    return false;
}

async function validateUserSession() {
    if(token != null) {
        if(await isUserSessionValid()) {
            return;
        }
    }
    localStorage.clear();
    sessionStorage.clear();
    location.replace("../login/login.html");
}

validateUserSession();

请问如何实现仅在所有异步函数执行完成后再加载页面元素?


解决方案

方案1:先隐藏页面,验证通过后再显示

这是最快捷的实现方式,通过CSS先隐藏页面内容,验证完成后再显示:

  1. 在home.css中添加隐藏样式:
body {
    display: none;
}
  1. 修改validateUserSession函数,验证通过后解除隐藏:
async function validateUserSession() {
    if(token != null) {
        if(await isUserSessionValid()) {
            // 验证通过,显示页面
            document.body.style.display = 'block';
            return;
        }
    }
    localStorage.clear();
    sessionStorage.clear();
    location.replace("../login/login.html");
}

可选:可以在隐藏期间添加加载动画,避免用户看到空白页面。

方案2:动态渲染页面内容

完全避免页面内容提前加载,验证通过后再将内容插入DOM:

  1. 修改HTML,只保留空的容器和内容模板:
<body>
    <div id="app-container"></div>
    <template id="page-content">
        <div class="header">
            <p id="home-txt" class="header-txt">Home</p>
            <p id="user-txt" class="header-txt">Olá, Nome!</p>
        </div>
        <div class="content">
            <iframe src="../notebooks/notebooks.html"></iframe>
        </div>
    </template>
</body>
  1. 更新validateUserSession函数,验证通过后渲染模板:
async function validateUserSession() {
    if(token != null) {
        if(await isUserSessionValid()) {
            // 克隆模板内容并插入容器
            const template = document.getElementById('page-content');
            const content = template.content.cloneNode(true);
            document.getElementById('app-container').appendChild(content);
            // 手动加载依赖脚本(比如home.js)
            const script = document.createElement('script');
            script.src = 'home.js';
            document.body.appendChild(script);
            return;
        }
    }
    localStorage.clear();
    sessionStorage.clear();
    location.replace("../login/login.html");
}

这种方式能确保iframe等资源不会提前请求,完全受控于验证结果。

方案3:让依赖脚本等待验证完成

如果需要保留原有HTML结构,可通过全局Promise让其他脚本等待验证结束:

  1. 修改isUserLogged.js,暴露验证Promise:
// 将验证函数的Promise暴露到全局
window.sessionValidation = validateUserSession();
  1. 修改home.js,等待验证完成后再执行逻辑:
(async function() {
    // 等待验证完成
    await window.sessionValidation;
    // 这里写原本home.js的业务逻辑
})();

同时去掉HTML中home.js的defer属性,避免脚本提前执行。


内容的提问来源于stack exchange,提问作者C410lol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:35:19