前端与数据库交互

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);
  }
);
相关推荐
灵感__idea1 小时前
Hello 算法:贪心的世界
前端·javascript·算法
GreenTea3 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd4 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌5 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈5 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫5 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝5 小时前
svg图片
前端·css·学习·html·css3
王夏奇6 小时前
python中的__all__ 具体用法
java·前端·python
大家的林语冰6 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong237 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习