禁用跨域访问是浏览器保证安全访问的一项重要策略限制,很多跨域访问的操作都是违逆浏览器标准的。在一些场合不得不又需要用到,则本文大致说明下,在Nginx作为服务端是如何解决跨域访问。
参数解释
一些主要的跨域参数
Access-Control-Allow-origin # 授权允许来源
Access-Control-Allow-Methods # 授权允许方法
Access-Control-Allow-Headers # 授权允许请求头
Access-Control-Expose-Headers # 可公开响应头
Access-Control-Allow-Credentials # 允许认证 即开放cookie
允许带cookie访问的配置
解释如下配置,允许 http://localhost:8080 整个来源进行访问。
Access-Control-Allow-Origin 支持 *,支持多个域名配置如:"http://localhost:8080,http://localhost:8081",用逗号进行隔开。
但此处因为有允许进行认证(授权cookie),即Origin不支持 * 也不支持多个域名配置,仅支持单项域名配置。
Access-Control-Allow-Methods 允许GET,POST,OPTIONS请求访问,如果想要支持其他请求将其加入其中。OPTIONS是预检请求,跨域中必须要将其开放。
Access-Control-Allow-Headers 允许客户端传递的header参数,如果客户端传递的header不在其中,则请求会失败。如需通过Authorization进行校验用户身份,则将Authorization配置到请求头。
同样,服务端如要返回其他响应头给客户端,也需指定,通过Access-Control-Expose-Headers配置,支持逗号隔开多个参数。
Access-Control-Allow-Credentials 允许授权cookie,允许必须为true,否则其它即禁用。
add_header Access-Control-Allow-Origin "http://localhost:8080";
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header Access-Control-Expose-Headers 'Authorization';
add_header Access-Control-Allow-Credentials 'true';
允许任何域名带cookie访问
此操作安全极低,如需要可如下配置。
set $origin $http_origin;
if ( $origin = '' ) {
set $origin "$scheme://$host:$server_port";
}
add_header Access-Control-Allow-Origin "$origin";
PHP允许任意域名跨域
支持中间件的可以放置在中间件中,但TP的中间件存在问题,如访问的代码存在问题,会导致报错,也会导致代码执行不到中间件,也就无法让option预检测请求通过,即TP建议将代码放置index.php
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 1728000');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
return;
}