[fastadmin] 第四十七篇 FastAdmin 解决 跨域问题
FastAdmin 解决跨域问题完整指南
问题场景
在使用 FastAdmin 进行前后端分离开发时,前端需要跨域请求后端 API 接口,经常遇到跨域访问被拒绝的问题。
Apache 服务器配置
1. 启用 headers 模块
首先确认 Apache 已启用 headers 模块:
# 宝塔环境检查模块状态
/www/server/apache/bin/httpd -M | grep headers
# 应该显示:headers_module (shared)
2. Apache 虚拟主机配置
在宝塔面板的站点配置文件中添加以下配置:
<VirtualHost *:443>
ServerAdmin webmaster@example.com
DocumentRoot "/www/wwwroot/your_project/public"
ServerName your-domain.com
# SSL 配置...
SSLEngine On
SSLCertificateFile /path/to/cert/fullchain.pem
SSLCertificateKeyFile /path/to/cert/privkey.pem
# 站点目录配置
<Directory "/www/wwwroot/your_project/public">
SetOutputFilter DEFLATE
Options +FollowSymlinks -Multiviews
AllowOverride All
Require all granted
DirectoryIndex index.php index.html index.htm
# 跨域配置 - 指定具体来源域名
Header always set Access-Control-Allow-Origin "https://your-frontend-domain.com"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control"
Header always set Access-Control-Allow-Credentials "true"
</Directory>
</VirtualHost>
注意要点:
- 使用
Header always set
而不是Header set
- 不能同时设置
Access-Control-Allow-Origin: *
和Access-Control-Allow-Credentials: true
- 需要指定具体的前端域名而不是通配符
*
常见问题排查
1. HTTPS 证书问题
在宝塔部署 SSL 证书时,确保下载并配置了完整的证书链,包括根证书。
2. 跨域配置无效
如果按上述配置仍报跨域错误,按以下步骤排查:
检查响应头
使用浏览器开发者工具查看响应头,确认是否包含跨域相关的 header:
Access-Control-Allow-Origin: https://your-frontend-domain.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control
查看 Apache 错误日志
tail -20 /www/wwwlogs/your-domain.com-error_log
服务器本地测试
curl -I https://your-domain.com/api/test
3. 403 Forbidden 错误
如果服务器本地访问返回 200,但浏览器跨域访问返回 403,通常是 FastAdmin 内置的跨域检测导致的。
临时调试方案
在 /www/wwwroot/your_project/public/index.php
开头添加调试代码:
<?php
// 调试跨域请求
error_log("Request: " . $_SERVER['REQUEST_METHOD'] . " " . $_SERVER['REQUEST_URI']);
error_log("Origin: " . ($_SERVER['HTTP_ORIGIN'] ?? 'none'));
// 如果是 API 请求,直接设置跨域头
if (strpos($_SERVER['REQUEST_URI'], '/api/') !== false) {
header("Access-Control-Allow-Origin: https://your-frontend-domain.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control");
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit();
}
}
// 原始的 ThinkPHP 启动代码...
最终解决方案:禁用 FastAdmin 跨域检测
经过排查发现,问题的根本原因是 FastAdmin 内置了跨域请求检测机制。
方法1:注释跨域检测函数
找到 /www/wwwroot/your_project/thinkphp/helper.php
文件,将跨域检测代码注释掉:
// 注释掉这行
// check_cors_request();
方法2:修改控制器权限
在具体的 API 控制器中设置不需要登录验证:
<?php
namespace app\api\controller;
use app\common\controller\Api;
class YourController extends Api
{
// 设置不需要登录的方法
protected $noNeedLogin = ['*'];
// 设置不需要权限的方法
protected $noNeedRight = ['*'];
public function lists()
{
// 你的业务代码...
}
}
方法3:在公共文件中全局处理
修改 /www/wwwroot/your_project/thinkphp/start.php
:
// 在文件开头添加
if (strpos($_SERVER['REQUEST_URI'] ?? '', '/api/') !== false) {
header("Access-Control-Allow-Origin: https://your-frontend-domain.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control");
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit();
}
}
验证配置
配置完成后,通过浏览器开发者工具验证:
- Network 面板中 API 请求状态码为 200
- Response Headers 包含正确的 CORS 头
- 没有控制台跨域错误提示
总结
FastAdmin 的跨域问题主要源于其内置的跨域检测机制,通过合理配置 Apache 和修改 FastAdmin 相关代码可以完美解决。建议在生产环境中使用方法3的全局处理方式,既保证了安全性又解决了跨域问题。
本作品采用《CC 协议》,转载必须注明作者和本文链接