必须在服务端注入cors响应头并处理options预检请求。方法一:通过behavior在app_begin钩子中全局注入;方法二:控制器内手动header设置(仅调试);方法三:nginx配置(推荐生产环境)。

前端页面在 http://localhost:3000 调用 ThinkPHP5.0 后端接口时被浏览器拦截,提示“No 'Access-Control-Allow-Origin' header is present”,说明服务端未响应 CORS 协议,必须在请求生命周期早期注入合法响应头并正确处理 OPTIONS 预检请求。
方法一:全局行为(Behavior)注入响应头
该方式适用于 ThinkPHP5.0,利用框架的“行为”机制在应用开始阶段统一写入跨域头,不依赖中间件系统,兼容性最强。
第一步:在 application/behavior/ 目录下新建 Header.php 文件,内容如下:
```php
namespace appehavior;
use thinkResponse;
class Header
{
public function run(&$dispatch)
{
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
$headers = [
'Access-Control-Allow-Origin' => $origin,
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Headers' => 'X-Requested-With,Content-Type,Authorization,X-Token',
'Access-Control-Allow-Methods' => 'GET,POST,PUT,DELETE,OPTIONS'
];
if ($dispatch instanceof Response) {
$dispatch->header($headers);
} elseif ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
$response = new Response('', 204, $headers);
$dispatch = ['type' => 'response', 'response' => $response];
}
}
}
```
第二步:打开 application/tags.php,将 【app\behavior\Header】 添加到 'app_begin' 钩子数组中:
return [ // 应用开始 'app_begin' => ['app\behavior\Header'], // 其他钩子保持不变...];
注意:命名空间路径必须严格匹配文件实际位置,大小写错误会导致行为不触发。
方法二:控制器内手动设置(仅限调试或单接口)
适合快速验证、临时开放某个接口,但生产环境严禁使用——每次更新控制器都需重复添加,且无法覆盖 OPTIONS 请求。
在目标控制器方法最开头插入两行代码:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization");
如果该接口需要接收 Cookie 或 Token,请改用动态 Origin:
$origin = $_SERVER['HTTP_ORIGIN'] ?? '*';<br>header("Access-Control-Allow-Origin: $origin");<br>header("Access-Control-Allow-Credentials: true");
【切记:这两行必须放在任何 echo、var_dump、render() 或 return 之前,否则 headers already sent 错误会直接中断执行】
方法三:Nginx 层配置(推荐生产环境使用)
绕过 PHP 层逻辑,由 Web 服务器统一注入响应头,性能高、稳定性强,且天然支持 OPTIONS 预检响应。
编辑 Nginx 站点配置,在 server 或 location 块内添加:
if ($request_method = 'OPTIONS') {<br> add_header Access-Control-Allow-Origin "$http_origin";<br> add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";<br> add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Token";<br> add_header Access-Control-Allow-Credentials "true";<br> add_header Access-Control-Max-Age 1728000;<br> add_header Content-Length 0;<br> add_header Content-Type text/plain;<br> return 204;<br>}
再补充通用头(放在 if 外部):
add_header Access-Control-Allow-Origin "$http_origin";<br>add_header Access-Control-Allow-Credentials "true";
重载 Nginx 配置:nginx -s reload。此方案无需修改任何 PHP 代码,也避免了 PHP 层 header 冲突风险。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











