跳至正文

PHP解决跨域 常用方法

前置知识

接口站点 nginx 配置 添加请求头 和 自动响应

#表示允许这个域跨域调用(客户端发送请求的域名和端口) 
#$http_origin动态获取请求客户端请求的域,不用*的原因是带cookie的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;

#表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers $http_access_control_request_headers;

#指定允许跨域的方法,* 代表所有
add_header Access-Control-Allow-Methods "GET,POST,PUT,PATCH,DELETE,OPTIONS";

#带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;

#预检命令的缓存,如果不缓存每次会发送两次请求 单位s
add_header Access-Control-Max-Age 3600;

#自动响应options请求
if ($request_method = OPTIONS){
    return 204;
}

页面站点 nginx 配置 使用反向代理请求接口

通过代理将页面站点和接口站点变成同域

前置条件:页面的路由不能和接口路由存在冲突,否则路由无法代理到接口

ex: 所有接口的前缀都是/api 且页面路由中不存在 /api前缀

location = /api {
  proxy_pass http://apihost;
}

PHP响应增加请求头

此方法也可用于不支持自动跨域php框架,在框架入口文件 或者 路由文件 最上方增加 header

header("Access-Control-Allow-Origin: *"); //允许请求来源
header("Access-Control-Allow-Credentials : true"); //允许携带cookies
header("Access-Control-Allow-Headers: *");//允许请求头
header("Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS");//允许请求方法
header("Access-Control-Max-Age: 3600");//预检请求缓存时间

Laravel 框架

使用laravel-cors 扩展包

laravel 7.0 以后版本 官方集成了 laravel-cors 扩展包 文档

return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'], //触发cors的路由前缀

    'allowed_methods' => ['*'],//允许请求方法

    'allowed_origins' => ['*'], //允许请求来源

    'allowed_origins_patterns' => [],//允许请求来源,正则表达式匹配

    'allowed_headers' => ['*'], //允许请求头

    'exposed_headers' => [], //排除的请求头

    'max_age' => 0, //预检请求缓存时间

    'supports_credentials' => false, //是否允许携带cookie
];

参考

MDN文档 跨域资源共享