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) 。

相关推荐
IM架构师7 小时前
# 一次老旧PHPCMS网站入侵排查:从SQL注入到PHP后门,以及IP白名单止血
sql·tcp/ip·php
码途行者8 小时前
处理超时未支付订单:两套轻量化方案,附 PHP 极简实现
开发语言·redis·php
vx_Biye_Design8 小时前
PHP中医养生馆预约系统60841-计算机课程设计、毕业设计
vue.js·spring boot·后端·mysql·php·课程设计·express
.Bryce.9 小时前
你了解 Blackboard(黑板系统)吗?听说过基于黑板系统实现的智能体吗?
java·网络·gpt·php·agent·codex·黑板系统
yu_zhidun18 小时前
企业电脑监控软件怎么选:别只看功能清单,先看这 6 个底层能力
开发语言·电脑·php·域智盾系统
李纲明19 小时前
WordPress 白屏排查手册:关插件、换主题、开调试、查 PHP(附停手信号)
开发语言·php·wordpress·故障排查·白屏·插件冲突
天远API1 天前
零信任架构实战:基于天远公安二要素政务版构建自动化不动产交易与契税核算实名核实网关
人工智能·架构·自动化·php
WeiXin_DZbishe1 天前
基于springboot装修风格选择系统的设计与开发-计算机毕设【课程设计】77964
java·vue.js·spring boot·后端·python·php·课程设计
anew___1 天前
《从零手写操作系统 (49):虚拟内存进阶——Demand Paging、Swap与缺页异常处理》
linux·服务器·php
misty youth1 天前
Navicat与PHPstudy小皮
mysql·adb·php·navicat