php处理跨域请求

在 PHP 中处理跨域请求,核心是通过设置 CORS(跨域资源共享)响应头,让浏览器允许前端从不同源(协议、域名或端口不同)发起的请求。以下是关键要点和实现方式:


一、基础 CORS 响应头设置

在 PHP 脚本最开头(任何输出前)添加以下代码:

```php

// 允许任意域名访问(仅限开发环境)

header('Access-Control-Allow-Origin: *');

// 允许的 HTTP 方法

header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');

// 允许的请求头

header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

// 处理预检请求(OPTIONS)

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {

http_response_code(200);

exit();

}

```

> ⚠️ 注意:`header()` 必须在任何输出(包括空格、BOM、`echo`、`var_dump` 等)之前调用,否则会报 `headers already sent` 错误 。


二、生产环境安全配置

不要使用 `*` 通配符,尤其当请求需携带凭证(如 Cookie、Authorization 头)时:

```php

$allowedOrigins = [

'https://your-frontend.com',

'https://www.your-frontend.com'

];

origin = _SERVER['HTTP_ORIGIN'] ?? '';

if (in_array(origin, allowedOrigins)) {

header('Access-Control-Allow-Origin: ' . $origin);

header('Vary: Origin'); // 避免缓存问题,尤其对 Safari/iOS 重要

}

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

header('Access-Control-Allow-Methods: GET, POST, OPTIONS');

header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {

http_response_code(200);

exit();

}

```

> 🔒 关键规则:

> - `Access-Control-Allow-Origin` 不能为 `*`,必须明确指定域名,当同时使用 `Access-Control-Allow-Credentials: true` 时 。


三、处理预检请求(Preflight)

浏览器在发送 非简单请求(如带自定义头、`Content-Type: application/json`、`PUT/DELETE` 方法)前,会先发 `OPTIONS` 预检请求。PHP 必须正确响应:

  • 返回 `200 OK`

  • 包含必要的 CORS 头

  • 不要执行后续业务逻辑,直接 `exit()`


四、其他注意事项

  • 编码问题:确保 PHP 文件为 无 BOM 的 UTF-8 编码,避免在 `<?php` 前输出隐藏字节 。

  • 框架推荐:如使用 Laravel,可安装官方中间件 [`fruitcake/laravel-cors`](https://github.com/fruitcake/laravel-cors) 统一管理 。

  • Web 服务器层配置:也可在 Nginx 或 Apache 中设置 CORS 头,避免 PHP 代码侵入 :

  • Nginx:使用 `add_header` 指令

  • Apache:在 `.htaccess` 中用 `Header set`


五、常见错误排查

| 问题 | 原因 | 解决方案 |

|------|------|----------|

| `No 'Access-Control-Allow-Origin' header` | `header()` 被输出干扰或未执行 | 检查文件开头是否有空格/BOM,确保在 `session_start()` 等之前调用 |

| 预检失败(405 Method Not Allowed) | 未处理 `OPTIONS` 请求 | 在入口添加 `if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit(); }` |

| 带 Cookie 仍被拒绝 | 使用了 `*` 通配符 | 改为指定具体域名,并设置 `Access-Control-Allow-Credentials: true` |


如需完整示例代码,可参考:[菜鸟教程 - PHP Ajax 跨域问题最佳解决方案](https://www.runoob.com/w3cnote/php-ajax-cross-border.html) 。

相关推荐
安妮的小熊呢2 小时前
CRMEB开源商城系统 & 标准版系统(PHP)开发规范
开发语言·javascript·php
在角落发呆3 小时前
跨越网络鸿沟:传统文件传输与现代内网穿透的奇妙交响
开发语言·php
minji...5 小时前
Linux 网络基础之网络IP层(十)IP 协议,网段划分,IP地址相关问题
linux·运维·服务器·网络·tcp/ip·智能路由器·php
枫叶林FYL6 小时前
【强化学习】2 大规模并行强化学习中的耦合策略优化:受控多样性驱动的样本高效探索
开发语言·php
zb200641207 小时前
Laravel 8.x新特性全解析
php·laravel
code monkey.7 小时前
【Linux之旅】Linux 网络基础全解析:从协议分层到 Socket 编程,构建高性能网络服务的底层基石
linux·网络·php
我命由我123457 小时前
PHP - PHP 基本随机数生成函数
开发语言·ide·后端·java-ee·php·intellij-idea·intellij idea
我命由我123457 小时前
PHP - PHP 简易 Web 服务器、基础接口开发
服务器·开发语言·前端·php·intellij-idea·idea·intellij idea
郝学胜-神的一滴7 小时前
系统设计 012:从用户系统出发,吃透缓存、数据库与高并发设计
java·数据库·python·缓存·php·软件构建
不正经的小寒21 小时前
PHP 8.2 核心特性
php