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

相关推荐
两个人的幸福12 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo14 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack14 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820715 天前
PHP 扩展——从入门到理解
php
鹏仔先生16 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下16 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip16 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
酉鬼女又兒16 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog25016 天前
不要再继续优化 TCP
网络协议·tcp/ip·php
Channing Lewis16 天前
PHP 解析 Excel 的那些坑:一次“行号错位”引发的数据丢失
开发语言·php·excel