|
|
@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
const express = require('express');
|
|
|
|
|
|
|
|
const cors = require('cors');
|
|
|
|
|
|
|
|
const morgan = require('morgan');
|
|
|
|
|
|
|
|
const rateLimit = require('express-rate-limit');
|
|
|
|
|
|
|
|
const { body, validationResult } = require('express-validator');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建 Express 应用实例
|
|
|
|
|
|
|
|
const app = express();
|
|
|
|
|
|
|
|
const PORT = 3000; // 可以根据需要修改端口
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用中间件
|
|
|
|
|
|
|
|
app.use(cors()); // 允许跨域请求
|
|
|
|
|
|
|
|
app.use(express.json()); // 解析 JSON 请求体
|
|
|
|
|
|
|
|
app.use(morgan('combined')); // 记录请求日志
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 请求速率限制
|
|
|
|
|
|
|
|
const limiter = rateLimit({
|
|
|
|
|
|
|
|
windowMs: 15 * 60 * 1000, // 15分钟
|
|
|
|
|
|
|
|
max: 100 // 每个IP最多100个请求
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
app.use(limiter);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟的用户数据(在实际应用中,这通常来自数据库)
|
|
|
|
|
|
|
|
const users = [
|
|
|
|
|
|
|
|
{ username: 'user1', password: 'password1' },
|
|
|
|
|
|
|
|
{ username: 'user2', password: 'password2' }
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟的数据
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
|
|
|
title: "欢迎使用系统",
|
|
|
|
|
|
|
|
description: "这是一个模拟的系统,用于展示数据与交互"
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 登录接口
|
|
|
|
|
|
|
|
app.post('/api/login', [
|
|
|
|
|
|
|
|
body('username').isString().notEmpty(),
|
|
|
|
|
|
|
|
body('password').isString().notEmpty()
|
|
|
|
|
|
|
|
], (req, res) => {
|
|
|
|
|
|
|
|
const errors = validationResult(req);
|
|
|
|
|
|
|
|
if (!errors.isEmpty()) {
|
|
|
|
|
|
|
|
return res.status(400).json({ errors: errors.array() });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { username, password } = req.body;
|
|
|
|
|
|
|
|
const user = users.find(u => u.username === username && u.password === password);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
|
|
|
|
return res.status(200).json({ message: 'Login successful!' });
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return res.status(401).json({ message: 'Invalid username or password.' });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取数据接口
|
|
|
|
|
|
|
|
app.get('/api/data', (req, res) => {
|
|
|
|
|
|
|
|
return res.status(200).json(data);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 提交成绩接口
|
|
|
|
|
|
|
|
app.post('/api/submit-grade', [
|
|
|
|
|
|
|
|
body('grade').isNumeric()
|
|
|
|
|
|
|
|
], (req, res) => {
|
|
|
|
|
|
|
|
const errors = validationResult(req);
|
|
|
|
|
|
|
|
if (!errors.isEmpty()) {
|
|
|
|
|
|
|
|
return res.status(400).json({ errors: errors.array() });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { grade } = req.body;
|
|
|
|
|
|
|
|
console.log(`Received grade: ${grade}`);
|
|
|
|
|
|
|
|
return res.status(200).json({ message: 'Grade submitted successfully!', grade });
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 全局错误处理
|
|
|
|
|
|
|
|
app.use((err, req, res, next) => {
|
|
|
|
|
|
|
|
console.error(err.stack);
|
|
|
|
|
|
|
|
res.status(500).send('Something broke!');
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 启动服务器
|
|
|
|
|
|
|
|
app.listen(PORT, () => {
|
|
|
|
|
|
|
|
console.log(`Server is running on http://localhost:${PORT}`);
|
|
|
|
|
|
|
|
});
|