You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

本地Docker容器API跨域请求CORS预检重定向问题排查

解决跨域请求中CORS预检请求重定向的错误

我刚碰到过类似的问题,咱们一步步来排查和解决:

问题根源分析

你遇到的错误核心是浏览器发送的OPTIONS预检请求被服务器重定向了,而CORS策略不允许预检请求有重定向行为。结合你的配置来看,可能的触发原因有两个:

  • 你的.htaccess里开启了+Indexes,如果api/cache/clear-all恰好是一个实际存在的目录,服务器会自动把不带斜杠的请求重定向到带斜杠的版本(比如/api/cache/clear-all/api/cache/clear-all/
  • 即使不是目录,请求在经过Rewrite规则处理时,也可能因为URL格式触发隐式重定向,而OPTIONS请求在到达你的index.php之前就被重定向了,导致重定向响应里没有你设置的CORS头,浏览器直接报错。

具体解决方案

1. 在.htaccess中优先处理OPTIONS预检请求

直接在.htaccess最顶部添加规则,拦截OPTIONS请求并返回正确的CORS头,避免它进入后续的Rewrite流程:

# 先处理OPTIONS预检请求,直接返回200和CORS头
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]

# 全局设置CORS响应头
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, POST, PATCH, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Origin, Content-Type, X-Auth-Token, X-Requested-With"

# 保留你原有的Rewrite规则
RewriteBase /api
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?request=$1 [QSA,NC,L]

Options All +Indexes
allow from all

注意:要确保你的Apache服务器启用了mod_headers模块,否则Header指令会失效。Linux环境下可以用a2enmod headers命令启用。

2. 修复请求URL的斜杠问题

从你的XHR详情看到,实际请求的URL是http://websites.click/api/cache/clear-all/(末尾多了斜杠),但你的Axios代码里写的是不带斜杠的。这种不一致很容易触发服务器的自动重定向,你可以:

  • 检查api/cache/clear-all是否是实际存在的目录,如果是,要么删除这个目录,要么在Axios请求里统一加上末尾斜杠
  • 修改Axios请求的URL,明确保持格式一致:
    window.axios.get('//websites.click/api/cache/clear-all', { })
      .then(response => { console.log(response); })
    

3. 验证index.php的CORS头设置

虽然我们在.htaccess里处理了OPTIONS请求,但实际的GET请求还是会走到index.php,所以你原来设置的CORS头可以保留,但要确保在输出任何内容之前就发送这些头(比如不要在echo、print等输出之后才加header),避免出现"headers already sent"的错误。

为什么这样能解决问题?

通过在.htaccess里直接处理OPTIONS请求,我们让浏览器的预检请求直接得到带CORS头的200响应,不会进入后续的Rewrite或重定向流程,从根源上避免了"预检请求不允许重定向"的错误。同时统一URL格式,也能减少不必要的重定向触发。

内容的提问来源于stack exchange,提问作者Martyn Ball

火山引擎 最新活动