合 Nginx配置跨域访问
Tags: NginxAccess-Control-Allow-Origin跨域访问
什么是跨域访问
在A网站中,我们希望使用Ajax来获得B网站中的特定内容。如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题。你可以理解为两个域名之间不能跨过域名来发送请求或者请求数据,否则就是不安全的。跨域访问违反了同源策略,同源策略规定,浏览器的ajax只能访问跟它的HTML页面同源(相同域名或IP的资源)。
如何确定是跨域请求
- A域名资源请求到B/C……域名
- 你当前访问的域名是http的,但请求的部分资源是https的
- 当使用ajax访问远程服务器时,请求失败,浏览器报如上错误。这是出于安全的考虑,默认禁止跨域访问导致的。
如果是跨域访问,这时候就会报错
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
错误场景如:我的WordPress报错:Fonts –No 'Access-Control-Allow-Origin',已经提示我字体文件请求http url跨域了,然后根据我用的服务环境设置如下就行,参考:https://www.uedbox.com/post/50992/
Nginx跨域设置No Access-Control-Allow-Origin无效的解决办法
报错:Access to font at 'https://pic.dbaup.com/i/resource/iconfont.ttf?t=1501323857226' from origin 'https://www.dbaup.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
不能加载字体或图片
解决方案:在Nginx中配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | -- 我的用这个解决的(多域名) map $http_origin $allow_origin { default ""; "~^(https?://localhost(:[0-9]+)?)" $1; "~^(https?://127.0.0.1(:[0-9]+)?)" $1; "~^(https?://192.168.10.[\d]+(:[0-9]+)?)" $1; "~^https://www.dbaup.com" https://www.dbaup.com; "~^https://mp.weixin.qq.com" https://mp.weixin.qq.com; } server { # 解决has been blocked by CORS policy add_header 'Access-Control-Allow-Origin' $allow_origin; # add_header 'Access-Control-Allow-Origin' 'https://www.dbaup.com'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET,POST'; } -- 我的用这个解决的(单域名) add_header 'Access-Control-Allow-Origin' 'https://www.dbaup.com'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET,POST'; -- 或者 location ~* \.(eot|ttf|woff)$ { add_header Access-Control-Allow-Origin '*'; } set $origin '*';#写入需要跨域的请求地址 if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Max-Age' 1728000; 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' $origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' $origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; } |
参数 | 说明 |
---|---|
Control-Allow-Origin | 表示允许访问的外域请求。 |
Access-Control-Allow-Headers | 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。 |
Access-Control-Allow-Methods | 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。 |
Nginx允许指定单个域名跨域访问
1 2 3 4 5 6 7 8 9 10 11 | location /{ #add_header Access-Control-Allow-Origin *; #允许所有域名不安全 add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With'; if ($request_method = 'OPTIONS') { return 204; } ... } |
第一条指令:接受www.sundayle.com 跨域请求
第二条指令:当该标志为真时,响应于该请求是否可以被暴露(可选)
第三条指令:指定请求的方法,可以是GET, POST, OPTIONS, PUT, DELETE等(可选)
第四条指令:允许脚本访问的返回头(可选)
第五条指令:给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误,发送”预检请求”时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
Nginx允许多个域名跨域访问
方法一:使用IF(不建议)
虚拟主机比较多,不方便
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | server { 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | map $http_origin $allow_origin { default ""; "~^(https?://localhost(:[0-9]+)?)" $1; "~^(https?://127.0.0.1(:[0-9]+)?)" $1; "~^(https?://192.168.10.[\d]+(:[0-9]+)?)" $1; "~^https://www.sunday.com" https://www.sundayle.com; "~^https://m.sundayle.com" https://m.sundayle.com; "~^(https?://[\w]+.open.sundayle.com)" $1; #"~^(https?://([\w]+.)?[\w]+.open.sundayle.com)" $1; #允许一级和二级域名 } server { 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; } ... } |
跨域测试
1 2 3 4 | curl -I -X OPTIONS -H "Origin: https://www.sundayle.com" "https://api.sundayle.com" HTTP/1.1 200 OK Access-Control-Allow-Origin: https://www.sundayle.com ... |