老K博客 - 一个源码和技术分享的博客

FastAdmin 解决 跨域问题

老K博客
2025-06-14 / 0 评论 / 9 阅读 / 正在检测是否收录...
广告

问题场景

在使用 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. 没有控制台跨域错误提示
本文共 522 个字数,平均阅读时长 ≈ 2分钟
广告
0

打赏

海报

正在生成.....

评论 (0)

语录
取消
CC BY-NC-ND