Skip to content

HTTP 常见问题排查

跨域问题

问题现象

  • 浏览器控制台出现 CORS 错误
  • OPTIONS 预请求失败
  • 跨域携带 Cookie 失败

可能原因

  • 服务器未设置 CORS 响应头
  • 前端请求头配置不正确
  • 跨域请求携带了 credentials

排查步骤

  1. 检查浏览器控制台错误信息
  2. 查看网络请求中的 OPTIONS 请求
  3. 检查服务器响应头

解决方案

  • 服务器端:设置 Access-Control-Allow-OriginAccess-Control-Allow-Methods 等响应头
  • 前端:使用 Axios 时设置 withCredentials: true

代码示例

javascript
// 服务器端(Express)
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }
  next();
});

// 前端(Axios)
axios.defaults.withCredentials = true;

请求异常

问题现象

  • 请求发送失败
  • 请求超时
  • 重复请求
  • 请求参数传递错误

可能原因

  • 网络连接问题
  • 服务器响应慢
  • 前端代码逻辑问题
  • 参数格式不正确

排查步骤

  1. 检查网络连接
  2. 查看浏览器网络面板
  3. 检查请求参数格式
  4. 检查服务器日志

解决方案

  • 设置合理的超时时间
  • 实现请求防抖/节流
  • 检查参数格式和编码
  • 优化服务器响应速度

代码示例

javascript
// 设置超时时间
axios.defaults.timeout = 10000;

// 防止重复请求
const pendingRequests = new Map();
axios.interceptors.request.use(config => {
  const key = `${config.method}:${config.url}`;
  if (pendingRequests.has(key)) {
    return Promise.reject(new Error('重复请求'));
  }
  pendingRequests.set(key, true);
  return config;
}, error => {
  return Promise.reject(error);
});

axios.interceptors.response.use(response => {
  const key = `${response.config.method}:${response.config.url}`;
  pendingRequests.delete(key);
  return response;
}, error => {
  const key = `${error.config.method}:${error.config.url}`;
  pendingRequests.delete(key);
  return Promise.reject(error);
});

响应异常

问题现象

  • 状态码 401(未授权)
  • 状态码 403(禁止访问)
  • 状态码 404(接口不存在)
  • 状态码 500(服务器错误)
  • 状态码 502(网关错误)

可能原因

  • Token 过期或无效
  • 用户权限不足
  • 接口路径错误
  • 服务器内部错误
  • 网关配置错误

排查步骤

  1. 检查状态码和错误信息
  2. 验证 Token 是否有效
  3. 检查接口路径是否正确
  4. 查看服务器日志

解决方案

  • 401:重新登录获取 Token
  • 403:检查用户权限
  • 404:修正接口路径
  • 500/502:联系后端开发人员

代码示例

javascript
axios.interceptors.response.use(
  response => response,
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // Token 过期,跳转到登录页
          window.location.href = '/login';
          break;
        case 403:
          // 权限不足,显示提示
          alert('您没有权限访问此资源');
          break;
        case 404:
          // 接口不存在,显示提示
          alert('请求的资源不存在');
          break;
        case 500:
        case 502:
          // 服务器错误,显示提示
          alert('服务器内部错误,请稍后重试');
          break;
      }
    }
    return Promise.reject(error);
  }
);

缓存问题

问题现象

  • 浏览器缓存导致接口数据不更新
  • 缓存策略设置不当
  • 缓存清除困难

可能原因

  • 强缓存未过期
  • 协商缓存验证失败
  • 缓存策略配置错误

排查步骤

  1. 检查浏览器缓存设置
  2. 查看响应头中的缓存相关字段
  3. 检查服务器缓存配置

解决方案

  • 设置合理的缓存策略
  • 使用版本号或时间戳避免缓存
  • 手动清除浏览器缓存

代码示例

javascript
// 避免缓存的请求
axios.get('/api/data', {
  params: {
    _t: Date.now() // 添加时间戳
  }
});

// 设置缓存策略
axios.get('/api/data', {
  headers: {
    'Cache-Control': 'no-cache'
  }
});

安全问题

问题现象

  • XSS 攻击
  • CSRF 攻击
  • 请求参数泄露
  • HTTPS 配置问题

可能原因

  • 输入验证不足
  • 缺少 CSRF 令牌
  • 明文传输敏感信息
  • HTTPS 配置错误

排查步骤

  1. 检查输入验证
  2. 检查 CSRF 防护措施
  3. 检查请求是否使用 HTTPS
  4. 检查敏感信息传输

解决方案

  • 实现输入验证和转义
  • 使用 CSRF 令牌
  • 加密敏感信息
  • 强制使用 HTTPS

代码示例

javascript
// CSRF 防护
axios.defaults.xsrfCookieName = 'XSRF-TOKEN';
axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN';

// 加密敏感信息
import CryptoJS from 'crypto-js';

const encryptData = (data, key) => {
  return CryptoJS.AES.encrypt(JSON.stringify(data), key).toString();
};

axios.post('/api/login', {
  username: 'user',
  password: encryptData('password', 'secretKey')
});

基于 VitePress 的本地知识库