插件窝 干货文章 Nginx怎么解决WebApi跨域二次请求及Vue单页面的问题

Nginx怎么解决WebApi跨域二次请求及Vue单页面的问题

请求 配置 Control header 1008    来源:    2025-04-22

解决Nginx中WebAPI跨域二次请求及Vue单页面问题

跨域二次请求问题分析

当浏览器发送跨域请求时,对于某些类型的请求(如带自定义头部的请求),浏览器会先发送一个OPTIONS方法的预检请求(preflight),待服务器响应允许后才会发送真正的请求。这会导致每个跨域API请求实际上发送两次。

解决方案

1. Nginx配置解决跨域

在Nginx配置中添加以下内容:

server {
    listen 80;
    server_name yourdomain.com;

    location /api/ {
        # 处理预检请求
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        # 处理实际请求
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;

        # 反向代理到实际API服务器
        proxy_pass http://api_server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

2. Vue单页面应用配置

对于Vue单页面应用,还需要确保:

  1. axios配置(在vue项目中):
import axios from 'axios';

// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000,
  withCredentials: true // 如果需要携带cookie
});

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    if (localStorage.getItem('token')) {
      config.headers['Authorization'] = 'Bearer ' + localStorage.getItem('token');
    }
    return config;
  },
  error => {
    // 对请求错误做些什么
    console.log(error);
    return Promise.reject(error);
  }
);
  1. 环境变量配置(.env文件):
VUE_APP_BASE_API = '/api'

3. 解决Vue单页面路由问题

在Nginx中添加以下配置处理Vue路由:

server {
    listen 80;
    server_name yourdomain.com;
    root /path/to/your/vue/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # API代理配置(同上)
    location /api/ {
        # ... 同上 ...
    }
}

高级配置建议

  1. 生产环境安全配置

    • 替换'*'为具体的允许域名
    • 考虑添加Access-Control-Allow-Credentials
    • 配置HTTPS
  2. 缓存优化

    • 增加Access-Control-Max-Age减少预检请求
  3. 日志监控

    • 监控OPTIONS请求频率
    • 记录跨域错误

常见问题排查

  1. 依然出现跨域错误

    • 检查Nginx配置是否生效(重启Nginx)
    • 检查响应头是否实际返回
    • 使用浏览器开发者工具查看网络请求
  2. Vue页面刷新404

    • 确保try_files配置正确
    • 检查Vue路由模式(history模式需要此配置)
  3. 认证相关问题

    • 如果需要携带cookie,确保配置withCredentials: true
    • 相应地在Nginx中配置Access-Control-Allow-Credentials: true

通过以上配置,应该能够解决WebAPI跨域二次请求问题,并确保Vue单页面应用正常工作。