跨域解决方案

1.什么是跨域?

为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。这叫作同源策略,同源策略是浏览器安全的基石。

如果一个请求地址里而的协议、城名和端口号都相同,就属于同源。
举个例子, 判断下面URL是否和http://www.a.com/a/a.html同源:
http://www.a.com/b/b.htinl,同源.
http//www.b.com/a/a.html, 不同源, 减名不相同.
https://www.a.com/b/b.html,不同源,协议不相同.
http://www.a.com:8080/b/b.html,不同源,端口号不相同.
依据浏览器同源策略,非同源脚本不可操作其他源下面的对象,想要操作其他源下的对象就需要跨域.综上所述, 在同源策略的限制下, 非同源的网站之间不能发送AJAX请求。如有需要,可通过降域或其他技术实现。

2.CORS技术

为了解决浏览器跨域问题,W3C提出了跨源资源共享方案。即CORS(Cross Origin-Source Sharing)。

CORS可以在不破坏即有规则的情况下, 通过后端服务器实现CORS接口, 从而实现跨域通信。CORS将请求分为两类:简单请求和非简单请求, 分别对跨域通信提供了支持。

2.1 简单请求

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

·Accept
·Accept-Language
·Content-Language
·Last-Event-ID
·Content-Type(仅限于[application/x-www-form-urlencoded、multipart/forn-data.text/plain]类型)
一个简单请求的例子:


GET /test HTTP/1.1
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Origin:http://www.test.com
Host:www.test.com


对于简单请求, CORS的策略是请求时在请求头中增加一个Origin字段, 服务器收到请求后,根据该字段判断是否允许该请求访问。
如果允许, 就在HTTP头信息中添加Access-Control-Allow-Origin字段, 并返回正确的结果.
如果不允许, 就不在HTTP头信息中添加Access-Control-Allow-Origin字段.
除了上面提到的Access-Control-Allow-Origin, 还有几个字段用于描述CORS返回结果:
·Access-Control-Allow-Credentials:可选, 用户是否可以发送、处理cookie,
·Access-Control-Expose-Headers:可选, 可以让用户拿到的字段.有几个字段无论设置与否都可以拿到的, 包括Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma.

2.2 非简单请求

对于非简单请求的跨源请求, 浏览器会在真实请求发出前增加一次OPTION请求, 称为预检请求(preflight request) .预检请求将真实请求的信息, 包括请求方法、自定义头字段、源信息添加到HTTP头信息字段中, 询问服务器是否允许这样的操作。
例如一个GET请求:


OPTIONS /test.HTTP/1.1
Origin:http://www.test.com
Access-Control-Request-Method:GET
Accemm-Control-Request-Headers:X-Cumtom-Header
Host:www.test.com


与CORS相关的字段有:
·请求使用的HTTP方法Access-Control-Request-Method.
·请求中包含的自定义头宇段Access-Control-Request-Headers.


服务器收到请求时,需要分别对Origin、Access-Control-Request-Method、Access-Control-Request-Headers进行验证, 验证通过后, 会在返回HTTP头信息中添加:


Access-Control-Allow-origin:http://www.test.com
Access-Control-Allow-Methods:GET, POST, PUT, DELETE
Access-Control-Allow-Headers:x-custom-Header
Accems-Control-AIlow-Credentials:true
Access-Control-Max-Aqe:1728000


它们的含义分别是:
Access-Control-Allow-Methods:真实请求允许的方法,
Ace ess-Control-Allow-Headers:服务器允许使用的宇段,
Ace ess-Control-Allow-Credentials:是否允许用户发送、处理cookie.
Access·Control-Max-Age:预检请求的有效期, 单位为秒.有效期内, 不会重复发送预检请求.
当预检请求通过后,浏览器才会发送真实请求到服务器。这样就实现了跨域资源的请求访问。


3.CORS实现

CORS的代码实现比较简单, 主要是要理解CORS实现跨域的原理和方式。在config包下新建一个CORS配置类, 实现WebMvcConfigurer接口。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") //允许跨域访问的路径
        .allowedOrigins("*") //允许跨域访问的源
        .allowedMethods("POST","GET","PUT","OPTIONS","DELETE") //允许请求方法
        .maxAge(168000) //预检间隔时间
        .allowedHeaders("*") //允许头部设置
        .allowCredentials(true);//是否发送cookie
    }
}

这样每当客户端发送请求的时候,都会在头部附上跨域信息,就可以支持跨域访问了。

原文地址:https://www.cnblogs.com/xc-xinxue/p/12489753.html