news 2026/6/7 5:19:28

PHP跨域资源共享CORS配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP跨域资源共享CORS配置

PHP跨域资源共享CORS配置

前后端分离架构中,跨域问题是必须处理的。CORS是浏览器允许跨域请求的机制。今天说说PHP中CORS的配置。

基础的CORS响应头。

```php
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');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
?>

带权限控制的CORS。

```php
class CorsMiddleware
{
private array $allowedOrigins;
private array $allowedMethods;
private array $allowedHeaders;

public function __construct(
array $allowedOrigins = ['*'],
array $allowedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
array $allowedHeaders = ['Content-Type', 'Authorization', 'X-Requested-With']
) {
$this->allowedOrigins = $allowedOrigins;
$this->allowedMethods = $allowedMethods;
$this->allowedHeaders = $allowedHeaders;
}

public function handle(): void
{
$origin = $_SERVER['HTTP_ORIGIN'] ?? '*';

if (in_array('*', $this->allowedOrigins)) {
header('Access-Control-Allow-Origin: *');
} elseif (in_array($origin, $this->allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
header('Vary: Origin');
}

header('Access-Control-Allow-Methods: ' . implode(', ', $this->allowedMethods));
header('Access-Control-Allow-Headers: ' . implode(', ', $this->allowedHeaders));
header('Access-Control-Max-Age: 86400');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
}

public function addOrigin(string $origin): void
{
if (!in_array($origin, $this->allowedOrigins)) {
$this->allowedOrigins[] = $origin;
}
}
}

$cors = new CorsMiddleware(['http://localhost:3000', 'https://myapp.com']);
$cors->addOrigin('https://admin.myapp.com');
$cors->handle();
?>

处理凭证(Cookie)的CORS。

```php
header('Access-Control-Allow-Origin: https://myapp.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');

// 使用凭证时,Access-Control-Allow-Origin不能是*
// 必须明确指定源
?>

自定义请求头的CORS。

```php
$allowedHeaders = ['Content-Type', 'Authorization', 'X-Custom-Header', 'X-Request-Id'];
header('Access-Control-Allow-Headers: ' . implode(', ', $allowedHeaders));

// 也可以在响应中暴露自定义头给前端
header('Access-Control-Expose-Headers: X-Total-Count, X-Request-Id');
?>

CORS中间件的完整实现。

```php
class CorsConfig
{
private static array $config = [
'allowed_origins' => ['*'],
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept'],
'exposed_headers' => ['X-Total-Count', 'X-Request-Id'],
'max_age' => 86400,
'allow_credentials' => false,
];

public static function configure(array $config): void
{
self::$config = array_merge(self::$config, $config);
}

public static function apply(): void
{
$origin = $_SERVER['HTTP_ORIGIN'] ?? '*';

if (self::$config['allow_credentials']) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Credentials: true');
} elseif (in_array('*', self::$config['allowed_origins'])) {
header('Access-Control-Allow-Origin: *');
} elseif (in_array($origin, self::$config['allowed_origins'])) {
header('Access-Control-Allow-Origin: ' . $origin);
}

header('Access-Control-Allow-Methods: ' . implode(', ', self::$config['allowed_methods']));
header('Access-Control-Allow-Headers: ' . implode(', ', self::$config['allowed_headers']));

if (!empty(self::$config['exposed_headers'])) {
header('Access-Control-Expose-Headers: ' . implode(', ', self::$config['exposed_headers']));
}

header('Access-Control-Max-Age: ' . self::$config['max_age']);

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
}
}

CorsConfig::configure([
'allowed_origins' => ['http://localhost:3000'],
'allow_credentials' => true,
]);
CorsConfig::apply();
?>

CORS是前后端分离必须处理的问题。开发环境可以宽放一些,生产环境要严格控制允许的源。使用凭证时Access-Control-Allow-Origin不能是*。OPTIONS预检请求要快速响应,不要做耗时操作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 5:15:01

pandas多维聚合实战:银行级生产环境优化指南

1. 项目概述:为什么多维聚合不是“加个groupby”就能搞定的事我在银行风控部门做过三年数据管道开发,后来跳槽到一家头部支付机构做BI平台架构。这期间最常被业务方拍着桌子问的一句话是:“上个月华东区餐饮类商户的交易金额中位数、手续费波…

作者头像 李华
网站建设 2026/6/7 5:11:59

统计幻觉破除指南:从p值失真到探索成本量化

1. 这不是“相关不等于因果”的老生常谈,而是一场统计思维的底层重装你肯定听过那句被说烂了的话:“相关不等于因果”。但如果你以为这篇文章只是在重复这个常识,那就大错特错了。它真正要撬动的,是整个现代统计实践的地基——我们…

作者头像 李华
网站建设 2026/6/7 5:11:00

避开这些坑!STM32驱动MFRC522读写M1卡(S50)的常见问题与调试心得

STM32与MFRC522读写M1卡实战:从硬件连接到软件调试的完整指南在物联网和智能设备快速发展的今天,非接触式IC卡技术已成为门禁系统、支付终端和身份识别等领域的重要组成部分。作为开发者,掌握STM32微控制器与MFRC522射频模块的协同工作方式&a…

作者头像 李华