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 小时前
DedeCMS plus/vote.php SQL注入漏洞修复教程
sql·php
fengci.2 小时前
php反序列化(复习)(第二章)
android·开发语言·学习·php
cch89182 小时前
五大PHP框架对比:如何选择最适合你的?
开发语言·php
cch89183 小时前
Laravel vs 主流PHP框架:终极对决
开发语言·php·laravel
代龙涛3 小时前
WordPress 首页模板怎么写(index.php 与 front-page.php)
android·php·android studio
航Hang*3 小时前
网络安全技术基础——第3章:网络攻击技术
运维·网络·笔记·安全·web安全·php
xuansec4 小时前
ThinkPHP 6.0.X 反序列化漏洞利用指南(PHPGGC 工具版)
安全·php
取码网4 小时前
最新轻量美化表白墙系统源码v2.0 带后台版 附搭建教程
php
&&Citrus13 小时前
【CPN学习笔记(二)】Chap2 非分层颜色 Petri 网——从一个简单协议开始读懂 CPN
笔记·学习·php·cpn·petri网