允许指定单个域名跨域访问
1 | location /{ |
第一条指令:接受www.sundayle.com 跨域请求
第二条指令:当该标志为真时,响应于该请求是否可以被暴露(可选)
第三条指令:指定请求的方法,可以是GET, POST, OPTIONS, PUT, DELETE等(可选)
第四条指令:允许脚本访问的返回头(可选)
第五条指令:给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误,发送”预检请求”时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
允许多个域名跨域访问
方法一:使用IF(不建议)
虚拟主机比较多,不方便1
2
3
4
5
6
7
8
9
10
11
12
13
14
15server {
set $allow_origin "";
if ( $http_origin ~ '^https?://(www|m).sundayle.com' ) {
set $allow_origin $http_origin;
}
location /{
add_header 'Access-Control-Allow-Origin' $allow_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
return 204;
}
...
}
方法二:使用MAP(建议)
1 | map $http_origin $allow_origin { |
跨域测试
1 | curl -I -X OPTIONS -H "Origin: https://www.sundayle.com" "https://api.sundayle.com" |
其他
Nginx 更多判断1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000; # 20days
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
Apache中启用CORS
在httpd配置或.htaccess文件中添加如下语句1
2SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1
Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
PHP中启用CORS
通过在服务端设置Access-Control-Allow-Origin响应头
允许所有来源访问1
2
3
header("Access-Control-Allow-Origin: *");
允许来自特定源的访问1
2
3
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
配置多个访问源
由于浏览器实现只支持了单个origin、*、null,如果要配置多个访问源,可以在代码中处理如下1
2
3
4
5
6
7
8
9
10
$allowe_origin = array(
"http://www.example.com" ,
"http://app.example.com" ,
"http://cms.example.com" ,
);
if (in_array($_SERVER['HTTP_ORIGIN'], $allowe_origin)){
@header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
HTML中启用CORS1
<meta http-equiv="Access-Control-Allow-Origin" content="*">
参考链接
正则表达式在线测试
Nginx 通过 CORS 实现跨域
阮一峰 跨域资源共享 CORS 详解