PHP 跨域问题解决方案
Php

PHP 跨域问题解决方案

蓝科迪梦
2025-09-26 / 0 评论 / 1 阅读 / 正在检测是否收录...

PHP 跨域问题解决方案

跨域问题(CORS - Cross-Origin Resource Sharing)是浏览器的安全机制,当网页尝试从不同源(协议、域名、端口)请求资源时会被阻止。以下是 PHP 中解决跨域问题的几种方法:

🔧 解决方案

1. 设置 CORS 响应头

在 PHP 脚本开始处添加必要的 CORS 头信息:

<?php
// 允许所有域名访问
header("Access-Control-Allow-Origin: *");

// 允许特定域名访问
header("Access-Control-Allow-Origin: https://example.com");

// 允许特定 HTTP 方法
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");

// 允许特定请求头
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");

// 允许携带凭证(cookies)
header("Access-Control-Allow-Credentials: true");

// 设置预检请求缓存时间
header("Access-Control-Max-Age: 86400"); // 24小时
?>

2. 处理预检请求(OPTIONS)

浏览器在发送复杂请求前会先发送 OPTIONS 预检请求:

<?php
// 检查请求方法
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    // 设置 CORS 头
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
    header("Access-Control-Allow-Headers: Content-Type, Authorization");
    header("Access-Control-Max-Age: 86400");
    
    // 直接返回 200 状态码,不执行后续代码
    http_response_code(200);
    exit();
}

// 正常处理请求
header("Access-Control-Allow-Origin: *");
// 其他业务逻辑...
?>

3. 创建 CORS 中间件函数

封装跨域处理逻辑:

<?php
function setCORSHeaders($allowedOrigins = [], $allowCredentials = false) {
    // 获取请求来源
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    
    // 如果没有指定允许的域名,则允许所有域名
    if (empty($allowedOrigins)) {
        header("Access-Control-Allow-Origin: *");
    } else {
        // 检查请求来源是否在允许列表中
        if (in_array($origin, $allowedOrigins)) {
            header("Access-Control-Allow-Origin: " . $origin);
        }
    }
    
    // 设置其他 CORS 头
    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
    header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
    
    if ($allowCredentials) {
        header("Access-Control-Allow-Credentials: true");
    }
    
    header("Access-Control-Max-Age: 86400");
}

// 使用示例
setCORSHeaders(['https://example.com', 'https://app.example.com'], true);
?>

4. 针对 API 接口的完整解决方案

<?php
class CORSHandler {
    private $allowedOrigins;
    private $allowCredentials;
    
    public function __construct($allowedOrigins = [], $allowCredentials = false) {
        $this->allowedOrigins = $allowedOrigins;
        $this->allowCredentials = $allowCredentials;
    }
    
    public function handle() {
        // 处理预检请求
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            $this->setHeaders();
            http_response_code(200);
            exit();
        }
        
        // 设置常规请求头
        $this->setHeaders();
    }
    
    private function setHeaders() {
        $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
        
        if (empty($this->allowedOrigins)) {
            header("Access-Control-Allow-Origin: *");
        } else {
            if (in_array($origin, $this->allowedOrigins)) {
                header("Access-Control-Allow-Origin: " . $origin);
            }
        }
        
        header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
        header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
        
        if ($this->allowCredentials) {
            header("Access-Control-Allow-Credentials: true");
        }
        
        header("Access-Control-Max-Age: 86400");
    }
}

// 使用示例
$cors = new CORSHandler(['https://example.com'], true);
$cors->handle();

// 你的 API 逻辑
echo json_encode(['status' => 'success']);
?>

5. 在框架中的处理方式

Laravel 中的 CORS 处理:

// 在中间件中处理
// app/Http/Middleware/CorsMiddleware.php
public function handle($request, Closure $next) {
    $response = $next($request);
    
    $response->headers->set('Access-Control-Allow-Origin', '*');
    $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    
    return $response;
}

🛡️ 安全注意事项

  1. 避免使用通配符:生产环境中不要使用 Access-Control-Allow-Origin: *,应该指定具体的域名
  2. 凭证安全:如果需要携带凭证(cookies),不要使用通配符,必须指定具体域名
  3. 方法限制:只允许必要的 HTTP 方法
  4. 请求头限制:只允许必要的自定义请求头

📝 最佳实践

  • 在应用入口处统一处理 CORS
  • 根据环境配置不同的 CORS 策略
  • 记录跨域请求日志用于监控
  • 定期审查允许的域名列表

通过以上方法,可以有效解决 PHP 应用中的跨域问题,确保前后端能够正常通信。

0

评论

博主关闭了所有页面的评论