[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();
    }
}

验证配置

配置完成后,通过浏览器开发者工具验证:

  1. Network 面板中 API 请求状态码为 200
  2. Response Headers 包含正确的 CORS 头
  3. 没有控制台跨域错误提示

总结

FastAdmin 的跨域问题主要源于其内置的跨域检测机制,通过合理配置 Apache 和修改 FastAdmin 相关代码可以完美解决。建议在生产环境中使用方法3的全局处理方式,既保证了安全性又解决了跨域问题。

本作品采用《CC 协议》,转载必须注明作者和本文链接
• 15年技术深耕:理论扎实 + 实战丰富,教学经验让复杂技术变简单 • 8年企业历练:不仅懂技术,更懂业务落地与项目实操 • 全栈服务力:技术培训 | 软件定制开发 | AI智能化升级 关注「上海PHP自学中心」获取实战干货
wangchunbo
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
司机 @ 某医疗行业
文章
313
粉丝
353
喜欢
565
收藏
1135
排名:61
访问:12.6 万
私信
所有博文
社区赞助商