有时候我们想对某个项目进行跨域访问限制,不管是静态目录文件,还是其他。动态文件还好说,可以在代码里添加,如php:
header('Access-Control-Allow-Origin: http://www.a.com')
header('Access-Control-Allow-Origin: http://www.b.com')
但静态目录文件,如图片等,就麻烦了,别急,这时就可以考nginx解决
location ~* \.ico|jpg|gif|png|js|css|woff2|ttf$ {
if ($http_origin ~ [a-z]+\.a|b\.com$){ # xxx.a.com或xxx.b.com域名才可以访问
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Request-Method GET;
}
root /usr/local/ad/ui; #存放静态文件的路径
expires 1h;
}
当然,仅在localtion下设置有效范围不够大,如果我们想对整个server进行设置,可以做如下配置:
server {
set $cors_origin "";
set $cors_cred "";
if ($http_origin ~ "^https.[a-z]+\.a|b\.com$") {
set $cors_origin $http_origin;
set $cors_cred true;
}
add_header Access-Control-Allow-Origin $cors_origin;
add_header Access-Control-Allow-Credentials $cors_cred;
add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept';#服务端可以接收的header
add_header Access-Control-Allow-Methods 'GET,POST';
add_header Access-Control-Allow-Credentials, true;#服务端接收认证信息,如cookie
}
注意 server里的配置不能与location里的一样,会报错:nginx: [emerg] "add_header" directive is not allowed here in /usr/local......
1: 简单请求 :
http请求方法的值限于三者之一:get,put,post;
Content-Type的值仅限于三者之一:text/plain,multipart/form-data,application/x-www-form-urlencoded;
除了被用户代理自动设置的首部字段(例如 Connection ,User-Agent)和在 Fetch 规范中定义为 禁用首部名称 的其他首部,允许人为设置的字段为 Fetch 规范定义的 对 CORS 安全的首部字段集合。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (需要注意额外的限制)
DPR
Downlink
Save-Data
Viewport-Width
Width
2:复杂请求
除了简单请求都是复杂请求,我们大多数时候都是 ajax请求的Content-Type:application/json 这样的复杂请求导致的。
简单请求如果设置了Authentication认证header也会让请求“升级”为复杂请。
简单请求相比于复杂请求少了一步 预检请求,也就是http的OPTIONS请求
这些规则在现代浏览器都是有实现的。
和shell规则很像。
=:等值比较;
~:与指定正则表达式模式匹配时返回“真”,区分字符大小写;
~*:与指定正则表达式模式匹配时返回“真”,不区分字符大小写;
!~:与指定正则表达式模式不匹配时返回“真”,区分字符大小写;
!~*:与指定正则表达式模式不匹配时返回“真”,不区分字符大小写;
-f, !-f:判断指定的路径是否为存在且为文件;
-d, !-d:判断指定的路径是否为存在且为目录;
-e, !-e:判断指定的路径是否存在,文件或目录均可;
-x, !-x:判断指定路径的文件是否存在且可执行;
HTTP访问控制(CORS)
Nginx Config for Cors - add_header directive is not allowed
为什么postman调接口不会跨域而浏览器会
ebay cors-filter 服务