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

如何将客户端变量传递至服务端密码验证功能?

问题解决:Web应用身份验证功能的JavaScript修正方案

核心问题定位

你的JavaScript代码存在以下关键问题,导致无法正确传递密码和员工编号到服务端:

  1. 参数名不匹配:服务端从Request.QueryString["tbemployeeNumber"]和Request.QueryString["SfUserPassword"]取值,但前端请求传的是UserID和password,参数名不一致导致服务端接收不到数据。
  2. 变量引用错误:console.log(SfUserPassword)中SfUserPassword未定义,应该打印获取到的password变量。
  3. 重复绑定事件:每次点击btnLoadOrder都会给btnSubmitPassword新增点击事件,多次点击后会触发多次请求。
  4. 未阻止默认提交行为:密码提交按钮的默认行为(如表单提交)未被阻止,可能导致页面刷新中断AJAX请求。
  5. 缺少页面返回时的密码验证触发逻辑:未监听页面前进/后退的pageshow事件来触发密码提示。

修正后的完整JavaScript代码

<script type="text/javascript">
// 提前缓存DOM元素,避免重复查询
const loadOrderButton = document.getElementById("<%= btnLoadOrder.ClientID %>");
const submitPasswordButton = document.getElementById("<%= btnSubmitPassword.ClientID %>");
const passwordPanel = document.getElementById("passwordPanel");
const passwordInput = document.getElementById("<%= SfUserPassword.ClientID %>");
const errorLabel = document.getElementById("<%= lblPasswordError.ClientID %>");
const employeeNumberInput = document.getElementById("<%= tbEmployeeNumber.ClientID %>");

// 抽离密码验证请求为复用函数
function validatePassword(employeeNumber, password) {
    return new Promise((resolve, reject) => {
        const xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(this.responseText.trim() === "true");
                } else {
                    reject(new Error("请求失败"));
                }
            }
        };
        // 匹配服务端的参数名:tbemployeeNumber 和 SfUserPassword,同时编码参数避免特殊字符问题
        const url = `ShopFloorEntryNew.aspx?tbemployeeNumber=${encodeURIComponent(employeeNumber)}&SfUserPassword=${encodeURIComponent(password)}`;
        xmlhttp.open("GET", url, true);
        xmlhttp.send();
    });
}

// 显示密码面板并重置状态
function showPasswordPanel() {
    errorLabel.style.display = "none";
    passwordInput.value = "";
    passwordPanel.style.display = "block";
    passwordInput.focus();
}

// 密码提交逻辑
submitPasswordButton.addEventListener("click", async (event) => {
    event.preventDefault(); // 阻止按钮默认提交行为,避免页面刷新
    const employeeNumber = employeeNumberInput.value.trim();
    const password = passwordInput.value.trim();

    // 空值校验
    if (!employeeNumber || !password) {
        errorLabel.innerHTML = "请输入员工编号和密码";
        errorLabel.style.display = "block";
        return;
    }

    try {
        const isCorrect = await validatePassword(employeeNumber, password);
        if (isCorrect) {
            console.log("密码验证通过");
            passwordPanel.style.display = "none";
            // 执行原本的loadOrder操作:移除阻止默认行为的监听,再触发按钮点击
            loadOrderButton.removeEventListener("click", handleLoadOrderClick);
            loadOrderButton.click();
        } else {
            errorLabel.innerHTML = "密码错误,请重新输入";
            errorLabel.style.display = "block";
            passwordInput.select();
        }
    } catch (err) {
        errorLabel.innerHTML = "验证请求失败,请稍后重试";
        errorLabel.style.display = "block";
    }
});

// loadOrder按钮点击逻辑
function handleLoadOrderClick(event) {
    const employeeNumber = employeeNumberInput.value.trim();
    if (!employeeNumber) {
        errorLabel.innerHTML = "请先输入员工编号";
        errorLabel.style.display = "block";
        event.preventDefault();
        return;
    }
    event.preventDefault();
    showPasswordPanel();
}

loadOrderButton.addEventListener("click", handleLoadOrderClick);

// 监听页面前进/后退事件,从缓存返回时触发密码验证
window.addEventListener("pageshow", (event) => {
    if (event.persisted) {
        showPasswordPanel();
    }
});
</script>

服务端代码补充修正

你的CheckPassword函数存在逻辑错误:调用SfGetUserPassword时传入的是页面控件tbEmployeeNumber.Text.Trim,而非函数参数employeeNumber,会导致始终用页面初始值查询,修正如下:

Private Function CheckPassword(employeeNumber As String, password As String) As Boolean
    ' 修正:使用传入的employeeNumber参数查询数据库
    Dim dt As DataTable = Users.SfGetUserPassword(employeeNumber.Trim)
    For Each row As DataRow In dt.Rows
        If row("UserId").ToString() = employeeNumber AndAlso row("SfUserPassword").ToString() = password Then
            Return True
        End If
    Next
    Return False
End Function

关键修改说明

  • 参数名匹配:AJAX请求URL的参数名改为tbemployeeNumber和SfUserPassword,与服务端取值键完全一致。
  • 事件绑定优化:将密码提交事件绑定移到外部,避免重复绑定;用Promise封装AJAX请求,让异步逻辑更清晰。
  • 默认行为阻止:给密码提交按钮添加event.preventDefault(),防止页面刷新中断验证流程。
  • 页面返回监听:通过pageshow事件监听浏览器前进/后退,当页面从缓存返回时自动弹出密码框。
  • 服务端逻辑修正:确保CheckPassword使用请求传递的员工编号查询数据库,而非页面控件的固定值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:31:02