页面报错Failed to load resource: the server responded with a status of 500 (Internal Server Error)     端口报错TypeError: Cannot destructure property 'title' of 'req.body' as it is undefined.
    at E:\baiyun\boke\routes\tag.js:18:13
    at Layer.handle [as handle_request] (E:\baiyun\node_modules\express\lib\router\layer.js:95:5)
    at next (E:\baiyun\node_modules\express\lib\router\route.js:149:13)
    at Route.dispatch (E:\baiyun\node_modules\express\lib\router\route.js:119:3)
    at Layer.handle [as handle_request] (E:\baiyun\node_modules\express\lib\router\layer.js:95:5)
    at E:\baiyun\node_modules\express\lib\router\index.js:284:15
    at Function.process_params (E:\baiyun\node_modules\express\lib\router\index.js:346:12)
    at next (E:\baiyun\node_modules\express\lib\router\index.js:280:10)
    at Function.handle (E:\baiyun\node_modules\express\lib\router\index.js:175:3)
    at router (E:\baiyun\node_modules\express\lib\router\index.js:47:12)
            const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const db = require('./db');
const userRoutes = require('./routes/user');
const tagRoutes = require('./routes/tag');
const app = express();


const PORT = process.env.PORT || 3000;


// 使用标签路由
app.use('/api/tags', tagRoutes);
// Middleware
app.use(cors());
app.use(bodyParser.json());
app.use(express.static('public'));


// 使用用户路由
app.use('/api/users', userRoutes);


// 根路由，返回 HTML 页面
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});


// 启动服务器
app.listen(PORT, () => {
    console.log(`服务器正在运行 http://localhost:${PORT}`);
});<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>User Tags</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4; /* 背景颜色 */
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: flex-start; /* 修改为 flex-start，使内容从顶部开始 */
            height: 100vh; /* 使内容垂直居中 */
            margin: 0;
        }
    .header {
            background-color: #333; /* 大标题背景颜色 */
            color: #fff; /* 大标题文字颜色 */
            width: 100%; /* 铺满页面宽度 */
            padding: 20px 0; /* 上下内边距 */
            text-align: left; /* 文字居中 */
        }
    .header h1{
            padding-left: 100px;
        }
    .container {
            display: flex;
            width: 80%; /* 容器宽度，可根据需要调整 */
            height: calc(100% - 80px); /* 减去 header 的高度 */
            margin-top: 20px; /* 与 header 的间距 */
        }
    .nav {
            width: 200px; /* 左边导航栏固定宽度 */
            padding: 20px;
            margin-left: -120px;
            margin-right: 130px;
        }
    .nav button {
            display: block;
            width: 100%;
            padding: 14px;
            border: none;
            background-color: #f4f4f4;
            cursor: pointer;
            color: black;
        }
    .nav button:hover {
            background-color: #f0f0f0;
        }
    .nav button.active {
            color: blue;
        }
    .nav #logoutButton {
            background-color: #f44336; /* 退出按钮的背景颜色 */
            color: #fff;
        }
    .nav #logoutButton:hover {
            background-color: #d32f2f;
        }
    .content {
            flex: 1; /* 右边内容区占据剩余空间 */
            padding: 20px;
            background-color: #F4F4F4; /* 修改内容区域的背景颜色 */
        }
        #tagList {
            list-style-type: none;
            padding: 0;
            background-color: #fff; /* 列表背景颜色 */
            border-radius: 5px; /* 圆角 */
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 阴影效果 */
        }
        #tagList li {
            padding: 15px; /* 增加内边距 */
            border-bottom: 1px solid #e0e0e0; /* 列表项之间的分隔线 */
        }
        #tagList li:last-child {
            border-bottom: none; /* 最后一个列表项不显示分隔线 */
        }
        #tagList li:hover {
            background-color: #f0f0f0; /* 鼠标悬停时的背景颜色 */
        }
    .tag-nav {
            display: flex;
            background-color: #f4f4f4; /* 新导航栏的背景颜色 */
            padding: 10px 0;
            border-bottom: 3px solid #ccc;
            position: relative;
        }
    .tag-nav button {
            margin-right: 10px;
            border: none;
            line-height: 34px;
            background-color: transparent;
            cursor: pointer;
            position: relative;
            top: 10px;
        }
    .tag-nav button:hover {
            text-decoration: underline;
        }
    .tag-nav button.active {
            color: blue;
            position: relative;
        }
    .tag-nav button.active::after {
            content: '';
            display: block;
            width: 100%;
            height: 3px;
            background-color: blue;
            position: absolute;
            bottom: -3px;
            left: 0;
        }
        /* 模态框样式 */
      .modal {
            display: none; /* 初始时隐藏 */
            position: fixed; /* 固定位置 */
            z-index: 1; /* 显示在最上层 */
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            overflow: auto; /* 启用滚动条 */
            background-color: rgba(0,0,0,0.4); /* 半透明背景 */
        }
      .modal-content {
            background-color: #fefefe;
            margin: 15% auto; /* 居中显示 */
            padding: 20px;
            border: 1px solid #888;
            width: 80%;
        }
      .close {
            color: #aaa;
            float: right;
            font-size: 28px;
            font-weight: bold;
        }
      .close:hover,
      .close:focus {
            color: black;
            text-decoration: none;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>博客系统</h1>
    </div>
    <div class="container">
        <div class="nav">
            <div id="loggedInUserInfo">
                <p id="usernameDisplay">用户名: <span></span></p>
            </div>
            <a href="/logout" id="logoutButton">退出</a>
            <button id="publishTagButton">发布标签</button> <!-- 发布标签按钮 -->
            <button class="active">首页</button>
            <button>我的粉丝</button>
            <button>我的关注</button>
            <button>我的文章</button>
            <button>关于我们</button>
        </div>
        <div class="content">
            <div class="tag-nav">
                <button class="active" data-category="recent">最近</button>
                <button data-category="tech">技术</button>
                <button data-category="life">生活</button>
            </div>
            <ul id="tagList">
                
            </ul>
        </div>
    </div>
    <!-- 模态框 -->
    <div id="publishTagModal" class="modal">
        <div class="modal-content">
            <span class="close">&times;</span>
            <form id="publishTagForm">
                <label for="tagTitle">标签标题：</label>
                <input type="text" id="tagTitle" required>
                <label for="tagContent">标签内容：</label>
                <textarea id="tagContent" required></textarea>
                <button type="submit">发布标签</button>
            </form>
        </div>
    </div>
    <script>
        async function fetchTags(category = 'recent') {
            const response = await fetch(`/api/tags?category=${category}`);
            const tags = await response.json();
            const tagList = document.getElementById('tagList');
            tagList.innerHTML = ''; // 清空当前标签
    
            tags.forEach(tag => {
                const li = document.createElement('li');
                li.innerHTML = `<h3>${tag.title}</h3><p>${tag.content}</p><p>${tag.time}</p>`; 
                tagList.appendChild(li);
            });
            const tagListWidth = document.getElementById('tagList').offsetWidth;
            const hr = document.querySelector('.tag-nav hr');
            if (hr) {
                hr.style.width = `${tagListWidth}px`;
            }
        }
    
        // 页面加载时自动调用获取标签
        fetchTags();
    
        // 为退出按钮添加点击事件
        document.getElementById('logoutButton').addEventListener('click', (event) => {
            event.preventDefault();
            window.location.href = '/index.html'; // 假设退出页面是 logout.html，根据实际情况修改
        });
    
        // 为标签导航栏按钮添加点击事件
        document.querySelectorAll('.tag-nav button').forEach(button => {
            button.addEventListener('click', async (event) => {
                // 移除所有按钮的 active 类
                document.querySelectorAll('.tag-nav button').forEach(btn => {
                    btn.classList.remove('active');
                });
                // 将当前点击的按钮添加 active 类
                event.target.classList.add('active');
                const category = event.target.getAttribute('data-category');
                fetchTags(category);
            });
        });
    
        // 为左边导航栏按钮添加点击事件
        document.querySelectorAll('.nav button').forEach(button => {
            button.addEventListener('click', () => {
                // 移除所有按钮的 active 类
                document.querySelectorAll('.nav button').forEach(btn => {
                    btn.classList.remove('active');
                });
                // 将当前点击的按钮添加 active 类
                button.classList.add('active');
            });
        });
    
        // 为发布标签按钮添加点击事件
        document.getElementById('publishTagButton').addEventListener('click', () => {
            // 显示模态框
            document.getElementById('publishTagModal').style.display = "block";
        });
    
        // 为关闭模态框按钮添加点击事件
        document.querySelector('.close').addEventListener('click', () => {
            document.getElementById('publishTagModal').style.display = "none";
        });
    
        // 为发布标签表单添加提交事件
        document.getElementById('publishTagForm').addEventListener('submit', async (event) => {
            event.preventDefault();
            const title = document.getElementById('tagTitle').value;
            const content = document.getElementById('tagContent').value;
            if (title && content) {
                const response = await fetch('/api/tags', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ title, content })
                });
                if (response.ok) {
                    fetchTags(); // 重新获取标签列表，以显示新添加的标签
                    // 关闭模态框
                    document.getElementById('publishTagModal').style.display = "none";
                } else {
                    alert('发布标签失败，请重试！');
                }
            }
        });
    
        // 假设从 localStorage 中获取登录用户信息，这里可以根据实际情况修改
        window.onload = function() {
            const username = localStorage.getItem('username');
            if (username) {
                document.getElementById('usernameDisplay').querySelector('span').textContent = username;
            }
        };
    </script>
</body>
</html>const express = require('express');
const router = express.Router();
const db = require('../db');


// 获取所有标签
router.get('/', (req, res) => {
    const sql = 'SELECT title, content, time FROM tags';
    db.query(sql, (err, results) => {
        if (err) {
            return res.status(500).json({ message: 'Error retrieving tags' });
        }
        res.status(200).json(results);
    });
});


// 新增：发布标签
router.post('/', (req, res) => {
    const { title, content } = req.body;
    const sql = 'INSERT INTO tags (title, content) VALUES (?,?)';
    db.query(sql, [title, content], (err, result) => {
        if (err) {
            console.error('Error publishing tag:', err); 
            return res.status(500).json({ message: 'Error publishing tag' });
        }
        res.status(201).json({ message: 'Tag published successfully' });
    });
});


module.exports = router;
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL
);


CREATE TABLE tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE blog_posts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    author VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO tags (name) VALUES ('JavaScript'), ('Node.js'), ('Express');修改代码，让他能够运行