前端与数据库交互

1. 前端角色:发起请求和处理响应

前端主要负责:

  • 收集用户输入数据

  • 通过HTTP请求调用后端API

  • 处理响应并更新UI

2. 基础前端代码示例(使用Fetch API)

javascript 复制代码
// API服务模块
class ApiService {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }

  // 查询数据
  async getItems() {
    try {
      const response = await fetch(`${this.baseURL}/api/items`);
      if (!response.ok) throw new Error('获取数据失败');
      return await response.json();
    } catch (error) {
      console.error('获取数据出错:', error);
      throw error;
    }
  }

  // 添加数据
  async addItem(itemData) {
    try {
      const response = await fetch(`${this.baseURL}/api/items`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(itemData)
      });
      if (!response.ok) throw new Error('添加失败');
      return await response.json();
    } catch (error) {
      console.error('添加数据出错:', error);
      throw error;
    }
  }

  // 更新数据
  async updateItem(id, updateData) {
    try {
      const response = await fetch(`${this.baseURL}/api/items/${id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(updateData)
      });
      if (!response.ok) throw new Error('更新失败');
      return await response.json();
    } catch (error) {
      console.error('更新数据出错:', error);
      throw error;
    }
  }

  // 删除数据
  async deleteItem(id) {
    try {
      const response = await fetch(`${this.baseURL}/api/items/${id}`, {
        method: 'DELETE'
      });
      if (!response.ok) throw new Error('删除失败');
      return true;
    } catch (error) {
      console.error('删除数据出错:', error);
      throw error;
    }
  }
}

// 使用示例
const api = new ApiService('https://your-backend.com');

// 获取并显示数据
async function loadAndDisplayItems() {
  const items = await api.getItems();
  // 更新UI显示数据
}

// 添加新项目
async function handleAddItem() {
  const newItem = {
    name: document.getElementById('itemName').value,
    description: document.getElementById('itemDesc').value
  };
  
  await api.addItem(newItem);
  await loadAndDisplayItems(); // 刷新数据
}

后端实现示例(Node.js + Express + MySQL)

了解后端如何实现可以帮助前端开发者更好地协作:

javascript 复制代码
// 后端API示例
const express = require('express');
const mysql = require('mysql2/promise');
require('dotenv').config();

const app = express();
app.use(express.json());

// 创建数据库连接池(生产环境使用环境变量)
const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: 10
});

// 获取所有项目
app.get('/api/items', async (req, res) => {
  try {
    const [rows] = await pool.execute('SELECT * FROM items');
    res.json(rows);
  } catch (error) {
    console.error('数据库查询错误:', error);
    res.status(500).json({ error: '服务器内部错误' });
  }
});

// 添加新项目
app.post('/api/items', async (req, res) => {
  try {
    const { name, description } = req.body;
    
    // 数据验证
    if (!name || !description) {
      return res.status(400).json({ error: '缺少必要字段' });
    }
    
    const [result] = await pool.execute(
      'INSERT INTO items (name, description) VALUES (?, ?)',
      [name, description]
    );
    
    res.status(201).json({ 
      id: result.insertId, 
      name, 
      description 
    });
  } catch (error) {
    console.error('数据库插入错误:', error);
    res.status(500).json({ error: '服务器内部错误' });
  }
});

// 更新项目
app.put('/api/items/:id', async (req, res) => {
  // ... 类似实现
});

// 删除项目
app.delete('/api/items/:id', async (req, res) => {
  // ... 类似实现
});

app.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});

现代前端数据管理方案

1. 使用状态管理库

javascript 复制代码
// 以React + TanStack Query为例
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

function ItemList() {
  const queryClient = useQueryClient();
  
  // 获取数据
  const { data: items, isLoading } = useQuery({
    queryKey: ['items'],
    queryFn: () => fetch('/api/items').then(res => res.json())
  });
  
  // 添加数据
  const addMutation = useMutation({
    mutationFn: (newItem) => 
      fetch('/api/items', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(newItem)
      }).then(res => res.json()),
    onSuccess: () => {
      queryClient.invalidateQueries(['items']); // 刷新数据
    }
  });
  
  // 类似地实现更新和删除...
}

2. 使用专门的HTTP客户端

  • Axios: 功能强大的HTTP客户端

  • SWR: React专用的数据获取库

  • RTK Query: Redux Toolkit的数据获取解决方案

实际项目中的最佳实践

1. 统一错误处理

javascript 复制代码
// 错误处理中间件
const handleApiError = async (response) => {
  if (!response.ok) {
    const error = await response.json().catch(() => ({}));
    throw new Error(error.message || `HTTP错误: ${response.status}`);
  }
  return response.json();
};

// 使用示例
fetch('/api/items')
  .then(handleApiError)
  .then(data => console.log(data))
  .catch(error => showErrorToast(error.message));

2. 请求拦截器(添加认证等)

javascript 复制代码
// Axios示例
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('auth_token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 响应拦截器处理常见错误
axios.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // 跳转到登录页
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);
相关推荐
saber_andlibert1 小时前
TCMalloc底层实现
java·前端·网络
逍遥德1 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
冻感糕人~1 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
程序员agions1 小时前
2026年,“配置工程师“终于死绝了
前端·程序人生
alice--小文子1 小时前
cursor-mcp工具使用
java·服务器·前端
晚霞的不甘1 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d
小迷糊的学习记录2 小时前
0.1 + 0.2 不等于 0.3
前端·javascript·面试
梦帮科技2 小时前
Node.js配置生成器CLI工具开发实战
前端·人工智能·windows·前端框架·node.js·json
VT.馒头3 小时前
【力扣】2695. 包装数组
前端·javascript·算法·leetcode·职场和发展·typescript
css趣多多3 小时前
一个UI内置组件el-scrollbar
前端·javascript·vue.js