前端JavaScript访问MSSQL Server数据表方式
前端JavaScript访问MSSQL Server数据表方式
在前端JavaScript中直接连接数据库是不安全的,通常需要通过后端API进行数据访问。以下是几种常见的前后端数据交互方式:
1. RESTful API (推荐)
前端代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户数据查询</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f7fa;
color: #333;
}
h1 {
color: #2c3e50;
text-align: center;
margin-bottom: 30px;
}
.container {
display: flex;
flex-direction: column;
gap: 20px;
}
.controls {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-wrap: wrap;
gap: 15px;
align-items: center;
}
button {
background-color: #3498db;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
transition: background-color 0.3s;
}
button:hover {
background-color: #2980b9;
}
table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
th, td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #e1e1e1;
}
th {
background-color: #3498db;
color: white;
font-weight: 600;
}
tr:hover {
background-color: #f5f7fa;
}
.loading {
text-align: center;
padding: 20px;
font-style: italic;
color: #7f8c8d;
}
.error {
color: #e74c3c;
padding: 10px;
background-color: #fadbd8;
border-radius: 4px;
margin: 10px 0;
}
.user-form {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.form-group {
display: flex;
flex-direction: column;
flex: 1;
min-width: 200px;
}
label {
margin-bottom: 5px;
font-weight: 500;
}
input, select {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.success {
color: #27ae60;
padding: 10px;
background-color: #d5f4e6;
border-radius: 4px;
margin: 10px 0;
}
</style>
</head>
<body>
<h1>用户数据管理系统</h1>
<div class="container">
<div class="controls">
<button id="loadUsers">加载用户数据</button>
<button id="addUserBtn">添加新用户</button>
<button id="clearData">清空数据</button>
</div>
<div id="userForm" class="user-form" style="display: none;">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" id="name" placeholder="输入姓名">
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" placeholder="输入邮箱">
</div>
<div class="form-group">
<label for="role">角色</label>
<select id="role">
<option value="user">普通用户</option>
<option value="admin">管理员</option>
</select>
</div>
<div class="form-group" style="align-self: flex-end;">
<button id="submitUser">提交</button>
<button id="cancelUser" style="background-color: #95a5a6;">取消</button>
</div>
</div>
<div id="message"></div>
<div id="userTable">
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>邮箱</th>
<th>角色</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="userTableBody">
<!-- 用户数据将在这里动态加载 -->
</tbody>
</table>
</div>
</div>
<script>
// API基础URL - 在实际应用中替换为真实的后端API地址
const API_BASE_URL = 'https://api.example.com/users';
// DOM元素
const loadUsersBtn = document.getElementById('loadUsers');
const addUserBtn = document.getElementById('addUserBtn');
const clearDataBtn = document.getElementById('clearData');
const userForm = document.getElementById('userForm');
const submitUserBtn = document.getElementById('submitUser');
const cancelUserBtn = document.getElementById('cancelUser');
const userTableBody = document.getElementById('userTableBody');
const messageDiv = document.getElementById('message');
// 事件监听
loadUsersBtn.addEventListener('click', loadUsers);
addUserBtn.addEventListener('click', () => userForm.style.display = 'flex');
clearDataBtn.addEventListener('click', clearTable);
submitUserBtn.addEventListener('click', addUser);
cancelUserBtn.addEventListener('click', () => userForm.style.display = 'none');
// 加载用户数据
async function loadUsers() {
showMessage('', '');
userTableBody.innerHTML = '<tr><td colspan="6" class="loading">正在加载数据...</td></tr>';
try {
const response = await fetch(API_BASE_URL);
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
const users = await response.json();
displayUsers(users);
} catch (error) {
console.error('获取用户数据失败:', error);
showMessage(`获取用户数据失败: ${error.message}`, 'error');
userTableBody.innerHTML = '<tr><td colspan="6" style="text-align: center; color: #e74c3c;">加载数据失败</td></tr>';
}
}
// 显示用户数据
function displayUsers(users) {
if (!users || users.length === 0) {
userTableBody.innerHTML = '<tr><td colspan="6" style="text-align: center;">暂无用户数据</td></tr>';
return;
}
userTableBody.innerHTML = users.map(user => `
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
<td>${user.role}</td>
<td>${new Date(user.createdAt).toLocaleString()}</td>
<td>
<button onclick="editUser(${user.id})" style="background-color: #f39c12;">编辑</button>
<button onclick="deleteUser(${user.id})" style="background-color: #e74c3c;">删除</button>
</td>
</tr>
`).join('');
}
// 添加新用户
async function addUser() {
const name = document.getElementById('name').value;
const email = document.getElementById('email').value;
const role = document.getElementById('role').value;
if (!name || !email) {
showMessage('请填写所有必填字段', 'error');
return;
}
try {
const response = await fetch(API_BASE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, email, role })
});
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
showMessage('用户添加成功!', 'success');
userForm.style.display = 'none';
document.getElementById('name').value = '';
document.getElementById('email').value = '';
document.getElementById('role').value = 'user';
// 重新加载用户列表
loadUsers();
} catch (error) {
console.error('添加用户失败:', error);
showMessage(`添加用户失败: ${error.message}`, 'error');
}
}
// 编辑用户
async function editUser(userId) {
// 在实际应用中,这里应该打开一个编辑表单
showMessage(`编辑用户ID: ${userId} (功能演示)`, 'success');
}
// 删除用户
async function deleteUser(userId) {
if (!confirm('确定要删除这个用户吗?')) {
return;
}
try {
const response = await fetch(`${API_BASE_URL}/${userId}`, {
method: 'DELETE'
});
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
showMessage('用户删除成功!', 'success');
loadUsers();
} catch (error) {
console.error('删除用户失败:', error);
showMessage(`删除用户失败: ${error.message}`, 'error');
}
}
// 清空表格
function clearTable() {
userTableBody.innerHTML = '<tr><td colspan="6" style="text-align: center;">数据已清空</td></tr>';
showMessage('表格数据已清空', 'success');
}
// 显示消息
function showMessage(message, type) {
messageDiv.textContent = message;
messageDiv.className = type;
}
// 页面加载时自动加载用户数据
document.addEventListener('DOMContentLoaded', loadUsers);
</script>
</body>
</html>
2. 后端技术栈示例
Node.js + Express + MSSQL
// server.js
const express = require('express');
const sql = require('mssql');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
// 数据库配置
const dbConfig = {
server: 'localhost',
database: 'YourDatabase',
user: 'YourUsername',
password: 'YourPassword',
options: {
encrypt: true, // 如果使用Azure,需要设置为true
trustServerCertificate: true // 本地开发使用
}
};
// 连接池
const pool = new sql.ConnectionPool(dbConfig);
const poolConnect = pool.connect();
// 获取所有用户
app.get('/api/users', async (req, res) => {
try {
await poolConnect;
const result = await pool.request().query('SELECT * FROM Users');
res.json(result.recordset);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// 添加新用户
app.post('/api/users', async (req, res) => {
const { name, email, role } = req.body;
try {
await poolConnect;
const result = await pool.request()
.input('name', sql.NVarChar, name)
.input('email', sql.NVarChar, email)
.input('role', sql.NVarChar, role)
.query('INSERT INTO Users (Name, Email, Role) OUTPUT INSERTED.* VALUES (@name, @email, @role)');
res.status(201).json(result.recordset[0]);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// 启动服务器
app.listen(3000, () => {
console.log('服务器运行在端口 3000');
});
3. 其他数据访问方式
GraphQL API
使用Apollo Server或类似库创建GraphQL端点
前端使用Apollo Client或简单fetch请求GraphQL API
WebSocket实时数据
适用于需要实时更新的应用
使用Socket.io或类似库
安全注意事项
1.永远不要在前端存储数据库凭据
2.使用环境变量保护后端数据库连接信息
3.实施适当的身份验证和授权
4.验证和清理所有用户输入
5.使用HTTPS保护数据传输
总结
前端JavaScript通过后端API访问MSSQL Server是最安全、最常用的方法。上面的示例展示了如何使用RESTful API实现完整的前后端数据交互,包括数据的增删改查操作。
在实际项目中,您需要:
设置真实的后端API端点
实现适当的错误处理
添加加载状态和用户反馈
实施适当的安全措施
浙公网安备 33010602011771号