前端与数据库交互

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);
  }
);
相关推荐
go_caipu3 分钟前
Vben Admin管理系统集成qiankun微服务(二)
前端·javascript
唐叔在学习7 分钟前
insertAdjacentHTML踩坑实录:AI没搞定的问题,我给搞定啦
前端·javascript·html
超绝大帅哥7 分钟前
Promise为什么比回调函数更好
前端
幸福小宝7 分钟前
uniapp 异型无缝轮播图
前端
wordbaby10 分钟前
TanStack Router 实战: 如何设置基础认证和受保护路由
前端
智算菩萨13 分钟前
Anthropic Claude 4.5:AI分层编排的革命,成本、速度与能力的新平衡
前端·人工智能
程序员Agions13 分钟前
程序员武学修炼手册(三):融会贯通——从写好代码到架构设计
前端·程序员·强化学习
zhouzhouya14 分钟前
我和TRAE的这一年:从"看不懂"到"玩得转"的AI学习进化史
前端·程序员·trae
小则又沐风a18 分钟前
数据结构->链表篇
前端·html
小王和八蛋22 分钟前
前端存储与离线应用实战:Cookie、LocalStorage、PWA 及 Service Worker 核心知识点
前端·javascript