跨域告警未开放Access-Control-Allow-Origin问题处理

502次阅读
没有评论

跨域告警未开放 Access-Control-Allow-Origin

跨域告警未开放 Access-Control-Allow-Origin 问题处理

解决方案:在对应网页 location 添加以下跨域配置:

Access-Control-Allow-Origin: *
或 Access-Control-Allow-Origin: 'http://doman:port'

1. 简单请求

在 CORS 出现前,发送 HTTP 请求时在头信息中不能包含任何自定义字段,且 HTTP 头信息不超过以下几个字段:

主动设置的头信息不能超过以下字段:

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type(只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain)

请求方法只能是:HEAD,GET,POST

浏览器会在 请求头信息 里增加一个 Origin 字段,表明本次请求的来源,若服务器返回的头部信息里需包含 Access-Control-Allow-Origin,并包含 Origin 则浏览器正常返回数据,否则出现跨域错误。

如果需要携带 cookie,请求时需设置 (比如 XMLHttpRequest.withCredentials = true)。若返回头部信息有 Access-Control-Allow-Credentials:true,则浏览器会正常返回数据,否则浏览器会拦截结果报 跨域错误。

注意:服务器会正常返回数据,只是浏览器拦截了结果。

服务器在返回头信息里设置(必须):

Access-Control-Allow-Origin: Origin
Eg:Access-Control-Allow-Origin:127.0.0.1:80

如果想设置匹配所有的 Origin 且不带 cookie 的,可以设置:

Access-Control-Allow-Origin: *

如果需要带 Cookie(用户是否可以发送、处理 cookie),需设置:

Access-Control-Allow-Credentials:true

如果想匹配所有的 Origin 且带 cookie:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: 请求的 Origin(从 request 获取后填入)千万不能同时设置 Credentials=true 且 Origin=*,浏览器会报错。Access-Control-Expose-Headers:可选,可以让用户拿到的字段。

有几个字段无论设置与否都可以拿到的,包括:

Cache-Control

Content-Language

Content-Type

Expires

Last-Modified

Pragma

2. 非简单请求

不能同时满足简单请求的 2 个条件。

常见的情况是请求方法是 PUT 或者 Content-Type 字段类型是 application/json 或者 头信息里自定义了属性

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers Accept,Origin,X-Requested-With,Content-Type,Last-Modified,JSESSIONID,token;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
if ($request_method = 'OPTIONS'){return 204;}

或者

add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;

解释:

1、Access-Control-Allow-Origin,这里使用变量 $http_origin 取得当前来源域,也可以用“*”代表允许所有;

2、Access-Control-Allow-Credentials,为 true 的时候指请求时可带上 Cookie,自己按情况配置吧;

3、Access-Control-Allow-Methods,OPTIONS 一定要有的,另外一般也就 GET 和 POST,如果你有其它的也可加进去;

4、Access-Control-Allow-Headers,这个要注意,里面一定要包含自定义的 http 头字段(就是说前端请求接口时,如果在 http 头里加了自定义的字段,这里配置一定要写上相应的字段),从上面可看到我写的比较长,我在网上搜索一些常用的写进去了,里面有“web-token”和“app-token”,这个是我项目里前端请求时设置的,所以我在这里要写上;

5、Access-Control-Expose-Headers,可不设置,看网上大致意思是默认只能获返回头的 6 个基本字段,要获取其它额外的,先在这设置才能获取它;

6、语句“if ($request_method =‘OPTIONS’) {”,因为浏览器判断是否允许跨域时会先往后端发一个 options 请求,然后根据返回的结果判断是否允许跨域请求,所以这里单独判断这个请求,然后直接返回;

完整跨域配置参考:

nginx:

server {
listen 80 default_server;
server_name _;

add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin $http_origin;

location /file {if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods $http_access_control_request_method;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
add_header Access-Control-Max-Age 1728000;
return 204;
}
}

}

java:

@Configuration
public class CorsConfig {
@Bean

public CorsFilter corsFilter() {final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 支持 cookie 跨域
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("*"));
config.setMaxAge(300L);// 设置时间有效

source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}

微信扫描下方的二维码阅读本文

正文完
 0
柹子丶
版权声明:本站原创文章,由 柹子丶 于2022-12-01发表,共计3685字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码