PHP接口设置http_response_code时触发CORS预检无HTTP ok状态错误如何解决
问题核心原因
CORS预检请求未单独处理,自定义状态码将非2xx响应返回给了OPTIONS请求,直接触发浏览器拦截。
原理说明
- 你前端请求携带了自定义
headers,属于非简单跨域请求,浏览器会自动先发OPTIONS方法的预检请求,提前校验跨域权限。 - 预检请求的规则是:必须返回2xx状态码+正确的CORS响应头,浏览器才会继续发送实际的业务请求。
- 你代码注释掉
http_response_code($code)时,所有请求(包括OPTIONS预检)的HTTP状态码固定为200,能通过预检校验。 - 启用
http_response_code($code)后,OPTIONS预检请求会和业务请求走相同的逻辑(比如鉴权校验、路由匹配),如果校验不通过/路由未匹配,就会返回401/404等非2xx状态码,直接被浏览器拦截。
修复方案
1. 优先处理OPTIONS预检请求
将OPTIONS逻辑放在所有业务校验、路由匹配的最前面,直接返回204无内容响应,不需要走后续业务逻辑:
// 入口文件最开头加这段逻辑 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: *"); header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); http_response_code(204); exit; }
2. 修正输出响应头
将原有Content-type从text/javascript改为标准JSON MIME类型:
header('Content-type: application/json; charset=utf-8');
3. 兼容旧浏览器优化(可选)
如果需要兼容不支持Access-Control-Allow-Headers: *的旧浏览器,可明确列出用到的自定义头:
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
补充说明
修改响应状态码本身不会影响CORS策略,仅当非2xx状态码被返回给OPTIONS预检请求时才会触发拦截。处理完预检逻辑后,你可以正常为业务请求设置200/400/404/401等任意状态码,不会影响跨域访问。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

