泰州市护送服务网

Vite前端API调用与本地开发代理配置策略详解

2026-03-26 12:40:01 浏览次数:1
详细信息

Vite前端API调用与本地开发代理配置详解

一、基础API调用方式

1.1 使用原生Fetch API

// 基础GET请求
async function fetchData() {
  try {
    const response = await fetch('/api/data');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('请求失败:', error);
  }
}

// POST请求示例
async function postData(url, data) {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  });
  return response.json();
}

1.2 使用Axios(推荐)

// 安装: npm install axios
import axios from 'axios';

// 创建实例
const api = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// 请求拦截器
api.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => Promise.reject(error)
);

// 响应拦截器
api.interceptors.response.use(
  response => response.data,
  error => {
    if (error.response?.status === 401) {
      // 处理未授权
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

// 使用示例
export const userAPI = {
  getUsers: () => api.get('/users'),
  createUser: (data) => api.post('/users', data),
  updateUser: (id, data) => api.put(`/users/${id}`, data),
};

二、Vite代理配置详解

2.1 基础代理配置

// vite.config.js / vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  server: {
    proxy: {
      // 简单代理配置
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
});

2.2 多环境代理配置

// vite.config.js
export default defineConfig(({ mode }) => {
  // 根据环境选择不同的代理配置
  const proxyConfig = {
    development: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
    },
    staging: {
      '/api': {
        target: 'https://staging-api.example.com',
        changeOrigin: true,
      },
    },
    production: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
      },
    },
  };

  return {
    server: {
      proxy: proxyConfig[mode] || proxyConfig.development,
    },
  };
});

2.3 高级代理配置示例

export default defineConfig({
  server: {
    proxy: {
      // 多个API端点
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },

      // WebSocket代理
      '/socket.io': {
        target: 'ws://localhost:3001',
        ws: true,
      },

      // 带身份验证的代理
      '/auth': {
        target: 'http://localhost:3002',
        changeOrigin: true,
        configure: (proxy, options) => {
          proxy.on('proxyReq', (proxyReq, req, res) => {
            // 添加自定义请求头
            proxyReq.setHeader('X-Special-Proxy-Header', 'vite-proxy');
          });
        },
      },

      // 路径前缀保留
      '/external-api/v1': {
        target: 'https://external-service.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/external-api/, '/api'),
      },
    },
  },
});

三、环境变量配置

3.1 环境变量文件

# .env.development
VITE_API_BASE_URL=http://localhost:3000
VITE_APP_NAME=MyApp Dev

# .env.production
VITE_API_BASE_URL=https://api.example.com
VITE_APP_NAME=MyApp

3.2 TypeScript支持

// env.d.ts
interface ImportMetaEnv {
  readonly VITE_API_BASE_URL: string;
  readonly VITE_APP_NAME: string;
  // 更多环境变量...
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

3.3 API服务封装

// src/services/api.ts
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';

class APIService {
  private axiosInstance: AxiosInstance;

  constructor() {
    this.axiosInstance = axios.create({
      baseURL: import.meta.env.VITE_API_BASE_URL,
      timeout: 15000,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    this.setupInterceptors();
  }

  private setupInterceptors() {
    // 请求拦截器
    this.axiosInstance.interceptors.request.use(
      config => this.handleRequest(config),
      error => Promise.reject(error)
    );

    // 响应拦截器
    this.axiosInstance.interceptors.response.use(
      response => this.handleResponse(response),
      error => this.handleError(error)
    );
  }

  private handleRequest(config: AxiosRequestConfig) {
    const token = localStorage.getItem('access_token');
    if (token) {
      config.headers = {
        ...config.headers,
        Authorization: `Bearer ${token}`,
      };
    }
    return config;
  }

  private handleResponse(response: any) {
    return response.data;
  }

  private handleError(error: any) {
    if (error.response?.status === 401) {
      // 刷新token逻辑
      return this.refreshTokenAndRetry(error.config);
    }

    if (error.response?.status === 403) {
      // 权限不足处理
      window.location.href = '/403';
    }

    return Promise.reject(error);
  }

  // API方法
  public get = (url: string, config?: AxiosRequestConfig) => 
    this.axiosInstance.get(url, config);

  public post = (url: string, data?: any, config?: AxiosRequestConfig) => 
    this.axiosInstance.post(url, data, config);

  // 其他HTTP方法...
}

export const apiService = new APIService();

四、实际项目架构示例

4.1 模块化API组织

src/
├── api/
│   ├── index.ts          # API入口文件
│   ├── auth.ts          # 认证相关API
│   ├── user.ts          # 用户相关API
│   ├── product.ts       # 产品相关API
│   └── types/          # TypeScript类型定义
│       ├── auth.ts
│       └── user.ts
├── services/
│   ├── api.ts          # API服务基类
│   └── request.ts      # 请求封装
└── utils/
    └── http.ts         # HTTP工具函数

4.2 类型安全的API调用

// src/api/types/user.ts
export interface User {
  id: number;
  name: string;
  email: string;
  avatar?: string;
}

export interface CreateUserDto {
  name: string;
  email: string;
  password: string;
}

// src/api/user.ts
import { apiService } from '@/services/api';
import type { User, CreateUserDto } from './types/user';

export const userAPI = {
  // 获取用户列表
  getUsers: (params?: {
    page?: number;
    limit?: number;
    search?: string;
  }) => apiService.get<User[]>('/users', { params }),

  // 创建用户
  createUser: (data: CreateUserDto) => 
    apiService.post<User>('/users', data),

  // 获取用户详情
  getUserById: (id: number) => 
    apiService.get<User>(`/users/${id}`),

  // 更新用户
  updateUser: (id: number, data: Partial<CreateUserDto>) => 
    apiService.put<User>(`/users/${id}`, data),

  // 删除用户
  deleteUser: (id: number) => 
    apiService.delete(`/users/${id}`),
};

五、开发调试技巧

5.1 Mock数据开发

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    // 使用vite-plugin-mock
    require('vite-plugin-mock')({
      mockPath: 'mock', // mock文件目录
      enable: true,     // 开发环境启用
    }),
  ],
});

// mock/user.js
export default [
  {
    url: '/api/users',
    method: 'get',
    response: () => ({
      code: 0,
      data: [
        { id: 1, name: '张三', email: 'zhangsan@example.com' },
        { id: 2, name: '李四', email: 'lisi@example.com' },
      ],
    }),
  },
];

5.2 网络请求监控

// 全局请求监控
const originalFetch = window.fetch;
window.fetch = function(...args) {
  const startTime = Date.now();
  console.log(`🚀 请求开始: ${args[0]}`);

  return originalFetch.apply(this, args).then(response => {
    console.log(`✅ 请求完成: ${args[0]}, 耗时: ${Date.now() - startTime}ms`);
    return response;
  }).catch(error => {
    console.error(`❌ 请求失败: ${args[0]}`, error);
    throw error;
  });
};

六、最佳实践总结

6.1 配置建议

环境隔离:区分开发、测试、生产环境的配置 类型安全:使用TypeScript确保API调用的类型安全 错误处理:统一的错误处理机制 请求拦截:添加loading状态、身份验证等通用逻辑 响应格式化:统一响应数据结构

6.2 性能优化

请求缓存:对不经常变化的数据进行缓存 请求取消:避免重复请求和竞态条件 分页加载:大数据列表使用分页 图片懒加载:优化图片资源加载

6.3 安全考虑

CSRF防护:添加CSRF token XSS防护:对用户输入进行过滤 敏感信息:避免在客户端存储敏感信息 HTTPS:生产环境强制使用HTTPS

通过以上配置和策略,可以在Vite项目中实现高效、安全、易维护的API调用和代理配置。

相关推荐