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

MySQL用户更新异常:仅修改Organization触发400错误

Node.js + MySQL 用户管理功能修改组织报错排查

修改用户的Username、Password、Role时能正常更新数据库条目,但仅修改Organization时,会收到POST http://localhost:3000/api/useredit 400(Bad Request)错误。

已确认:

  • 前端能正确获取并传递Organization ID到后端
  • 后端能接收到正确的Organization ID
  • 但后端if (organizationID)之后的代码无执行日志,数据库也无变更

相关代码

HTML/EJS 代码

<div class="Edit-Panel" style="display: none;">
    <div class="Edit-Wrapper">
        <div class="Editing">
            <p class="Edit-Header">Editing:</p>
            <p class="UserSelected">#usernamehere</p>
        </div>
        <div class="Edit-Inputs">
            <div class="Input-Bar">
                <input id="Edit-Username" class="Edit-Input" type="text" placeholder="Change Username">
                <i class="fa-solid fa-user"></i>
            </div>
            <div class="Input-Bar">
                <input id="Edit-Password" class="Edit-Input" type="text" placeholder="Change Password">
                <i class="fa-solid fa-lock"></i>
            </div>
            <div class="Input-Bar">
                <select name="User-Level" class="Drop-Down" id="Edit-Organization">
                    <option value="" disabled selected>Select Organization</option>
                    <% organizations.forEach(org => { %>
                        <option value="<%= org.organizationID %>"><%= org.organizationName %></option>
                    <% }); %>
                </select>
            </div>
            <div class="Input-Bar">
                <select name="Role" class="Drop-Down" id="Edit-Role">
                    <option value="" disabled selected>Edit Role</option>
                    <option value="Admin">Admin</option>
                    <option value="Teacher">Teacher</option>
                    <option value="Student">Student</option>
                </select>
            </div>
            <button class="Edit-Btn" id="Submit-Edit"> Submit Changes </button>
            <button class="Edit-Btn" id="Close-Edit"> Cancel </button>
        </div>
    </div>
</div> 

前端JS代码

const userId = localStorage.getItem('selectedUserId');
const editUsernameInput = document.getElementById('Edit-Username');
const editPasswordInput = document.getElementById('Edit-Password');
const editOrganizationSelect = document.getElementById('Edit-Organization');
const editRoleSelect = document.getElementById('Edit-Role');
const submitEditBtn = document.getElementById('Submit-Edit');

let editedFields = {};

editUsernameInput.addEventListener('input', function () {
    editedFields.username = editUsernameInput.value;
});

editPasswordInput.addEventListener('input', function () {
    editedFields.password = editPasswordInput.value;
});

editOrganizationSelect.addEventListener('change', function () {
    const selectedOption = editOrganizationSelect.options[editOrganizationSelect.selectedIndex];
    editedFields.organizationID = selectedOption.value; 
    console.log('Organization ID:', editedFields.organizationID); 
});

editRoleSelect.addEventListener('change', function () {
    editedFields.role = editRoleSelect.value;
});

submitEditBtn.addEventListener('click', function () {
    console.log(editedFields.organizationID);
    const requestBody = { userId, ...editedFields };

    fetch('/api/useredit', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
    })
    .then(response => {
        if (response.ok) {
            alert('Changes submitted successfully.');
            editedFields = {};
            editUsernameInput.value = '';
            editPasswordInput.value = '';
            editOrganizationSelect.selectedIndex = 0;
            editRoleSelect.selectedIndex = 0;
        } else {
            alert('Error submitting changes.');
        }
    })
    .catch(error => {
        alert('Error submitting changes:', error);
    });
});

后端Node.js代码

const express = require('express');
const router = express.Router();
const DBconnection = require('../DB/Connector');

router.post('/useredit', (req, res) => {
    const { userId, username, password, organizationID, role } = req.body;
    console.log('Received Organization ID:', organizationID);

    let updateFields = [];
    let updateValues = [];

    if (username) {
        updateFields.push('UserName = ?');
        updateValues.push(username);
    }
    if (password) {
        updateFields.push('UserPassword = ?');
        updateValues.push(password);
    }
    if (role) {
        updateFields.push('UserRole = ?');
        updateValues.push(role);
    }

    if (updateFields.length === 0) {
        return res.status(400).json({ error: 'No fields to update' });
    }

    updateValues.push(userId);

    const updateUserQuery = `UPDATE useraccounts SET ${updateFields.join(', ')} WHERE UserID = ?`;

    DBconnection.query(updateUserQuery, updateValues, (err, updateUserResult) => {
        if (err) {
            console.error("Error updating user:", err);
            return res.status(500).json({ error: 'Error updating user' });
        }

        if (organizationID) {
            const updateSectionLinkQuery = `UPDATE sectionlinks SET SectionID = ? WHERE UserID = ?`;
            const updateSectionLinkParams = [organizationID, userId];

            DBconnection.query(updateSectionLinkQuery, updateSectionLinkParams, (err, updateSectionLinkResult) => {
                if (err) {
                    console.error("Error updating sectionlink:", err);
                    return res.status(500).json({ error: 'Error updating sectionlink' });
                }

                console.log('Section Link Update Result:', updateSectionLinkResult);

                return res.status(200).json({ message: 'User updated successfully' });
            });
        } else {
            return res.status(200).json({ message: 'User updated successfully' });
        }
    });
});

module.exports = router; 

问题原因及修复

问题根源

仅修改Organization时,username、password、role都为空,导致后端的updateFields数组长度为0,触发了if (updateFields.length === 0)的判断,直接返回400错误,后续更新组织的代码根本没机会执行。

修复方案

修改后端代码,调整判断逻辑,允许仅更新组织ID的情况:

router.post('/useredit', (req, res) => {
    const { userId, username, password, organizationID, role } = req.body;
    console.log('Received Organization ID:', organizationID);

    let updateFields = [];
    let updateValues = [];

    if (username) {
        updateFields.push('UserName = ?');
        updateValues.push(username);
    }
    if (password) {
        updateFields.push('UserPassword = ?');
        updateValues.push(password);
    }
    if (role) {
        updateFields.push('UserRole = ?');
        updateValues.push(role);
    }

    // 调整判断:只有当既无常规字段更新,又无组织ID更新时才返回400
    if (updateFields.length === 0 && !organizationID) {
        return res.status(400).json({ error: 'No fields to update' });
    }

    // 处理常规字段更新
    if (updateFields.length > 0) {
        updateValues.push(userId);
        const updateUserQuery = `UPDATE useraccounts SET ${updateFields.join(', ')} WHERE UserID = ?`;

        DBconnection.query(updateUserQuery, updateValues, (err, updateUserResult) => {
            if (err) {
                console.error("Error updating user:", err);
                return res.status(500).json({ error: 'Error updating user' });
            }
            // 常规字段更新完成后处理组织ID
            handleOrganizationUpdate();
        });
    } else {
        // 无常规字段更新,直接处理组织ID
        handleOrganizationUpdate();
    }

    // 封装组织ID更新逻辑
    function handleOrganizationUpdate() {
        if (organizationID) {
            const updateSectionLinkQuery = `UPDATE sectionlinks SET SectionID = ? WHERE UserID = ?`;
            const updateSectionLinkParams = [organizationID, userId];

            DBconnection.query(updateSectionLinkQuery, updateSectionLinkParams, (err, updateSectionLinkResult) => {
                if (err) {
                    console.error("Error updating sectionlink:", err);
                    return res.status(500).json({ error: 'Error updating sectionlink' });
                }
                console.log('Section Link Update Result:', updateSectionLinkResult);
                return res.status(200).json({ message: 'User updated successfully' });
            });
        } else {
            return res.status(200).json({ message: 'User updated successfully' });
        }
    }
});

额外优化建议

  • 前端可在提交前增加校验,避免空提交,但后端必须保留兜底校验逻辑
  • 确认organizationID的类型与数据库中SectionID类型一致(如前端传递字符串时,需转换为数字类型再执行SQL)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:34:53