前端与数据库交互

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);
  }
);
相关推荐
u0111026751 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
jerrywus2 小时前
让 AI 写完代码后交一份报告:我改造了 answer-me-with-html
前端·claude·cursor
派小心.2 小时前
小程序分享链路中来源参数的传递校验
大数据·前端·数据库·人工智能·小程序·数据分析
hhb_6183 小时前
一键生成数据看板,ECharts实战演示
前端·javascript·echarts
Java后端的Ai之路3 小时前
08_React组件API
前端·react.js·前端框架
小马不起床3 小时前
零基础玩转 FastAPI_09:前端基础工程构建
前端·状态模式·fastapi
风骏时光牛马4 小时前
用户管理模块接口开发
前端
彭亚川Allen4 小时前
从零手搓 RAG 之检索全流程,给大模型接上自己的知识库
前端·后端·ai编程
IT_陈寒4 小时前
别让Java字符串拼接偷偷吃掉你的内存
前端·人工智能·后端
软件技术NINI5 小时前
圣罗兰彩妆html+css 4页
前端·css·html