跨域解决方案(CORS)
跨域解决方案(CORS)在Spring Boot 中解决跨域问题在spring Cloud中解决跨域问题在Nginx中解决跨域问题
跨域解决方案(CORS)
1. 什么是跨域?
跨域问题是出于浏览器的【同源策略】限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。
所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
由于我们现在是采用的前后端分离的微服务架构,前端和后端必定存在跨域问题。解决跨域问题可以采用CORS。
2. CORS简介
CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
CORS需要浏览器和服务器同时支持。但是目前基本上浏览器都支持,所以我们只要保证服务器端服务器实现了 CORS 接口,就可以跨源通信。
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
3. 具体解决方式
解决跨域问题,就是在服务器端给响应添加头信息
| Name | Required | Comments |
|---|---|---|
| Access-Control-Allow-Origin | 必填 | 允许请求的域 |
| Access-Control-Allow-Methods | 必填 | 允许请求的方法 |
| Access-Control-Allow-Headers | 可选 | 预检请求后,告知发送请求需要有的头部 |
| Access-Control-Allow-Credentials | 可选 | 表示是否允许发送cookie,默认false; |
| Access-Control-Max-Age | 可选 | 本次预检的有效期,单位:秒; |
3.1 在Spring Boot 中解决
-
在spring boot中给我们提供了 @CrossOrigin 注解用于解决跨域问题。
-
使用场景要求:jdk1.8+、Spring4.2+
-
只需要在我们需要的controller上加@CrossOrigin
@RestController //实现跨域注解 //origin="*"代表所有域名都可访问 //maxAge飞行前响应的缓存持续时间的最大年龄,简单来说就是Cookie的有效期 单位为秒若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失 @CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("/album") public class AlbumController {}
3.2 在spring Cloud中解决
只需要在spring Cloud Gateway 服务中添加配置就行
spring:
application:
name: system-gateway
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': # 匹配所有请求
allowedOrigins: "*" #跨域处理 允许所有的域
allowedMethods: # 支持的方法
- GET
- POST
- PUT
- DELETE
当然也可以自己利用Gateway的拦截器来手动添加相应的头信息
default-filters: - AddResponseHeader=Access-Control-Allow-Credentials,true - AddResponseHeader=Access-Control-Allow-Headers,access-control-allow-origin - AddResponseHeader=Access-Control-Allow-Methods,GET - AddResponseHeader=Access-Control-Allow-Origin,* - AddResponseHeader=Access-Control-Allow-Age,3600
3.3 在Nginx中解决
location /example {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Max-Age 1728000;
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 Content-Type' 'text/plain; charset=utf-8';
add_header Content-Length 0 ;
return 204;
}
+ if ($http_origin ~* (https?://(.+\.)?(example\.com$))) {
+ 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-Expose-Headers Content-Length,Content-Range;
+ }
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080/;
}
解释:
-
if ($request_method = 'OPTIONS') {...}当请求方法为 OPTIONS 时:
1、添加允许源Access-Control-Allow-Origin为 * (可根据业务需要更改)
2、添加缓存时长Access-Control-Max-Age,当下次请求时,无需再发送 OPTIONS 请求
3、添加允许的方法,允许的首部
4、添加一个内容长度为0,类型为text/plain; charset=utf-8, 返回状态码为204的首部 -
if ($http_origin ~* (https?://(.+\.)?(example\.com$))) {...}, 当 origin 为合法域名(可根据业务调整或去除合法域名验证)时:
1、添加允许源Access-Control-Allow-Origin为$http_origin(可根据业务需要更改)
2、添加允许认证Access-Control-Allow-Credentials为true,允许接收客户端 Cookie(可根据业务需要更改。 但要注意,当设置为true时,Access-Control-Allow-Origin不允许设置为 *)
3、添加允许的方法,暴露的首部
至此,完成跨域请求正确响应。
以上,是对跨域请求在Web Server的解决方案,主要是通过响应 OPTIONS 方法和添加允许源来解决。
更多推荐



所有评论(0)