必须用过滤器统一处理跨域,因options预检请求不经过控制器,header()无效;正确做法是创建corsfilter,在app/config/filters.php中注册,对options返回200并设cors头,对普通请求补全access-control-allow-origin等头。

CodeIgniter 4 必须用过滤器(Filter)统一处理跨域,不能只在控制器里加 header() 或 $this->output->set_header() —— 否则 OPTIONS 预检请求会失败,前端卡在“preflight request doesn't pass access control check”。
为什么控制器里设头无效
浏览器发起跨域请求前,会先发一个 OPTIONS 请求做预检。这个请求不经过你的控制器逻辑,而是由框架路由层直接拦截。你在控制器方法里写的 header() 根本不会执行,响应为空或 404/500,前端就停住不动了。
正确做法:写 CorsFilter 并注册
在 app/Filters/CorsFilter.php 中创建过滤器,对所有请求(含 OPTIONS)前置响应 CORS 头:
- 检查
Origin是否在白名单内,禁止*和credentials同时使用 - 对 OPTIONS 请求直接返回 200,并设置
Access-Control-Allow-Methods、Access-Control-Allow-Headers等头 - 对普通请求,在响应发出前补全
Access-Control-Allow-Origin、Access-Control-Allow-Credentials等 - 在
app/Config/Filters.php中注册该过滤器,配置为全局或按路径启用
带 Cookie 或认证时的特别注意
如果前端用了 credentials: 'include'(比如带 session 或 token),后端必须:
- 响应头中
Access-Control-Allow-Credentials: true -
Access-Control-Allow-Origin不能是*,必须写具体域名,如http://localhost:5173 - Cookie 发送时要显式设
'secure' => false(开发环境 HTTP 下),且cookie_path设为'/'
别漏掉 Nginx 层的配合(可选但推荐)
如果你用 Nginx 做反向代理,也可以在 server 或 location 块里统一加 CORS 头,更早拦截预检请求:
- 用
add_header设置基础头,注意加always参数确保错误响应也带 CORS 头 - 对
OPTIONS请求用return 204快速响应,避免进 PHP - 用
map指令实现 Origin 白名单动态回显,比硬编码更安全











