You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django+Vue分域名部署 VPN访问触发CORS拦截问题排查

问题根因

你遇到的间歇性CORS报错是多层CORS规则冲突+违反浏览器CORS安全规范+托管环境边缘节点拦截共同导致的,具体触发逻辑:

  1. 规范硬冲突:Django配置中开启了CORS_ALLOW_CREDENTIALS = True(允许跨域携带凭证),但.htaccess里又把Access-Control-Allow-Origin设为通配符*。浏览器CORS规范明确要求:只要请求携带凭证(Cookie、Authorization鉴权头、客户端证书等),Access-Control-Allow-Origin绝对不能用*,必须精确匹配请求源,这类响应会被浏览器直接拦截。
  2. 响应头重复:同时在Django的corsheaders中间件、.htaccess两个位置配置CORS规则,会导致最终响应里出现2条甚至多条Access-Control-Allow-Origin头,浏览器遇到重复的跨域允许源头会直接判定跨域校验失败。
  3. 托管环境特性:o2switch默认在网络边缘部署了缓存节点与基础WAF,部分网络(尤其是VPN链路、跨运营商链路)的请求会被边缘节点直接响应,根本不会转发到后端Django服务处理,这部分响应只会应用.htaccess里的规则,不会带上Django生成的CORS头;而直连源站的请求又会同时带上两层生成的CORS头,最终表现就是部分网络正常、部分网络报跨域错。
  4. 预检请求处理逻辑错误:.htaccess里直接对所有OPTIONS请求返回204状态码,没有做源校验,部分浏览器会把这类无有效源匹配的预检响应判定为跨域失败。
修复步骤

第一步:清理.htaccess里的所有CORS相关配置

把.htaccess里和CORS有关的行全部删掉,只保留HTTPS跳转规则,修改后的.htaccess内容如下:

RewriteEngine On 
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /

不要在Apache层面重复配置CORS,所有跨域逻辑统一交给Django的corsheaders处理,避免头重复。

第二步:修正Django的corsheaders配置

首先确认CORS_ALLOWED_ORIGINS和CORS_ORIGIN_WHITELIST里的域名写全协议,不能只写域名,要带上https://前缀,比如前端域名是https://frontend.example.com就必须写全,不能写成frontend.example.com,末尾不要加斜杠。
修正后的settings.py相关配置如下:

# 关闭全源允许
CORS_ORIGIN_ALLOW_ALL = False
# 允许跨域携带凭证
CORS_ALLOW_CREDENTIALS = True
# 填写带https前缀的前端完整域名
CORS_ALLOWED_ORIGINS = [
    'https://你的前端完整域名',
]
# 旧版本corsheaders需要该配置,值和CORS_ALLOWED_ORIGINS保持一致即可
CORS_ORIGIN_WHITELIST = [
    'https://你的前端完整域名',
]
CSRF_TRUSTED_ORIGINS = [
    'https://你的前端完整域名',
]
# 允许的请求头,覆盖默认值
CORS_ALLOW_HEADERS = [
    "accept",
    "accept-encoding",
    "authorization",
    "content-type",
    "dnt",
    "origin",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
    "cache-control",
    "depth",
    "x-file-size",
    "if-modified-since",
    "x-file-name",
]
# 允许的请求方法
CORS_ALLOW_METHODS = [
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
]
# 预检请求缓存时间,减少OPTIONS请求次数
CORS_PREFLIGHT_MAX_AGE = 1728000

ALLOWED_HOSTS = [
    '你的后端域名',
]

注意:CorsMiddleware的现有位置是正确的,必须放在SessionMiddleware之后、CommonMiddleware之前,不要调整顺序。

第三步:配置o2switch面板排除API路径的缓存

登录o2switch主机面板,找到缓存配置(Litespeed Cache或自带的Site Cache),把后端API路径(一般是/api/开头,根据自身路由配置调整)设置为不缓存,避免边缘节点返回不带正确CORS头的缓存响应。

第四步:验证修复

  1. 清掉浏览器所有站点缓存、HSTS缓存,重启浏览器
  2. 连接VPN访问前端,打开浏览器开发者工具的网络面板,查看任意接口请求的响应头:
    • 只能存在1条Access-Control-Allow-Origin头,值精确为你的前端域名
    • 存在Access-Control-Allow-Credentials: true头
    • 不存在重复的CORS相关头
  3. 切换不同网络环境(手机热点、家庭宽带、VPN)分别测试,所有环境接口请求正常即修复完成。
额外注意事项
  • 绝对不要在开启CORS_ALLOW_CREDENTIALS = True的情况下把Access-Control-Allow-Origin设为*,所有现代浏览器都会直接拦截这类响应,没有例外。
  • 跨域配置只需要在一层做,要么在Web服务器(Apache/Nginx)层做,要么在应用层(Django)做,两层同时做大概率会出现重复头问题。
  • o2switch的默认缓存规则会同时缓存静态资源和动态响应,如果API路径被缓存,跨域头很容易因为缓存版本不一致出现时好时坏的问题。

内容的提问来源于stack exchange,提问作者Slimen Chrif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 19:15:46