本文目录导读:

在PHP项目中处理跨域请求,主要涉及设置正确的HTTP响应头,以下是几种常见的处理方法:
基础跨域设置
最简单的示例
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
// 你的业务代码
echo json_encode(['message' => '跨域请求成功']);
?>
完整的生产环境配置
针对单个请求的处理
<?php
// 允许的域名
$allowedOrigins = [
'http://localhost:3000',
'https://yourdomain.com',
'https://*.yourdomain.com'
];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
// 检查来源域名
if (in_array($origin, $allowedOrigins)) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Credentials: true');
}
// 处理预检请求 (OPTIONS)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
header('Access-Control-Max-Age: 3600'); // 缓存预检请求结果1小时
header('Content-Type: text/plain charset=UTF-8');
header('Content-Length: 0');
http_response_code(204); // 无内容
exit;
}
// 其他HTTP方法继续处理
header('Content-Type: application/json; charset=utf-8');
// 你的业务逻辑
echo json_encode(['status' => 'success']);
?>
中间件方式(推荐)
创建一个CORS中间件类
<?php
class CorsMiddleware {
private $allowedOrigins = [];
private $allowedMethods = [];
private $allowedHeaders = [];
private $allowCredentials = false;
private $maxAge = 3600;
public function __construct(array $config = []) {
$this->allowedOrigins = $config['allowedOrigins'] ?? ['*'];
$this->allowedMethods = $config['allowedMethods'] ?? [
'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'
];
$this->allowedHeaders = $config['allowedHeaders'] ?? [
'Content-Type', 'Authorization', 'X-Requested-With'
];
$this->allowCredentials = $config['allowCredentials'] ?? false;
$this->maxAge = $config['maxAge'] ?? 3600;
}
public function handle() {
// 处理来源
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array('*', $this->allowedOrigins)) {
header('Access-Control-Allow-Origin: *');
} else if (in_array($origin, $this->allowedOrigins)) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Vary: Origin'); // 通知缓存系统
}
// 设置其他CORS头
header('Access-Control-Allow-Methods: ' . implode(', ', $this->allowedMethods));
header('Access-Control-Allow-Headers: ' . implode(', ', $this->allowedHeaders));
if ($this->allowCredentials) {
header('Access-Control-Allow-Credentials: true');
}
// 处理预检请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Max-Age: ' . $this->maxAge);
http_response_code(204);
exit;
}
}
}
// 使用示例
$corsConfig = [
'allowedOrigins' => [
'http://localhost:3000',
'https://api.yourdomain.com'
],
'allowedMethods' => ['GET', 'POST', 'PUT', 'DELETE'],
'allowCredentials' => true,
];
$cors = new CorsMiddleware($corsConfig);
$cors->handle();
// 后续业务逻辑
?>
在框架中的处理
Laravel 示例
// app/Http/Middleware/Cors.php
namespace App\Http\Middleware;
use Closure;
class Cors
{
public function handle($request, Closure $next)
{
$response = $next($request);
$response->header('Access-Control-Allow-Origin', '*');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return $response;
}
}
// 在 kernel.php 中注册中间件
protected $middleware = [
// ...
\App\Http\Middleware\Cors::class,
];
使用 .htaccess 文件(Apache服务器)
<IfModule mod_headers.c>
# 允许所有来源
Header set Access-Control-Allow-Origin "*"
# 或者指定来源
# Header set Access-Control-Allow-Origin "http://yourdomain.com"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
# 处理 OPTIONS 预检请求
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</IfModule>
重要注意事项
安全建议
// 生产环境不要使用 *
// 应该指定具体的域名
header('Access-Control-Allow-Origin: https://specific-domain.com');
// 如果使用凭证(cookies)则不能使用 *
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: https://specific-domain.com');
header('Vary: Origin'); // 重要:当使用动态Origin时需要设置
调试建议
// 开启错误显示
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// 日志记录
error_log('Origin: ' . ($_SERVER['HTTP_ORIGIN'] ?? 'none'));
error_log('Request Method: ' . $_SERVER['REQUEST_METHOD']);
最佳实践总结
- 明确限制来源:不要盲目使用 ,应该指定允许的具体域名
- 处理预检请求:对于复杂请求(自定义头等),正确处理 OPTIONS 请求
- 缓存预检结果:使用
Access-Control-Max-Age减少请求次数 - 安全凭证:如果需要传递 cookies,必须指定具体的来源域名
- 错误处理:当跨域失败时,确保返回适当的错误信息
选择合适的方案取决于你的项目需求和部署环境,对于简单的API,直接设置响应头即可;对于大型项目,建议使用中间件方式统一管理。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播