ThinkPHP 5.1
- 使用中间件设置响应头
ThinkPHP 5.1 及以上版本支持中间件,可以通过中间件统一设置跨域响应头。
步骤:
创建一个中间件文件,例如 CorsMiddleware.php:
namespace app\middleware;
class CorsMiddleware
{
public function handle($request, \Closure $next)
{
$response = $next($request);
// 设置跨域响应头
$response->header([
'Access-Control-Allow-Origin' => '*', // 允许所有域名访问
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS', // 允许的请求方法
'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With', // 允许的请求头
]);
return $response;
}
}
在 app/middleware.php 中注册中间件:
return [
// 其他中间件
\app\middleware\CorsMiddleware::class,
];
如果需要针对特定路由启用跨域,可以在路由中单独应用中间件:
Route::group(function () {
// 你的路由
})->middleware(\app\middleware\CorsMiddleware::class);
- 在控制器中设置响应头
如果不需要全局设置跨域,可以在控制器中手动设置响应头。
示例:
namespace app\controller;
use think\Response;
class Index
{
public function index()
{
// 设置跨域响应头
$response = Response::create('Hello, World!', 'json');
$response->header([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With',
]);
return $response;
}
}
- 处理 OPTIONS 预检请求
浏览器在发送跨域请求时,会先发送一个 OPTIONS 请求(预检请求),服务器需要正确处理该请求。
示例:
在路由中定义一个 OPTIONS 请求的路由:
Route::options('*', function () {
return Response::create()->code(204)->header([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With',
]);
});
ThinkPHP 6 的跨域配置
ThinkPHP 6 提供了更简单的跨域配置方式,可以在 config/cors.php 中配置跨域。
步骤:
创建 config/cors.php 文件:
return [
'allow_origin' => ['*'], // 允许的域名
'allow_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], // 允许的请求方法
'allow_headers' => ['Content-Type', 'Authorization', 'X-Requested-With'], // 允许的请求头
'expose_headers' => [], // 暴露的响应头
'max_age' => 0, // 预检请求缓存时间
'supports_credentials' => false, // 是否允许携带凭证
];
在 app/middleware.php 中启用跨域中间件:
return [
// 其他中间件
\think\middleware\AllowCrossDomain::class,
];
Nginx设置跨域
如果不想在代码中处理跨域,可以在 Web 服务器(如 Nginx 或 Apache)中配置跨域。
Nginx 配置:
server {
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With';
if ($request_method = 'OPTIONS') {
return 204;
}
}
}
Apache 设置跨域:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=204,L]
总结
中间件:推荐使用中间件统一处理跨域。
控制器:如果仅需局部跨域,可以在控制器中设置响应头。
OPTIONS 请求:确保正确处理预检请求。
服务器配置:可以通过 Nginx 或 Apache 配置跨域。
ThinkPHP 6:提供了更简单的跨域配置方式。
根据项目需求选择合适的方式即可!