跨域问题简介
所谓跨域就是我们从一个服务器去向另一个服务器发送请求,获取资源,这就是最简单的跨域(在分布式架构中经常使用)。另外跨域还有多种变现形式,如: 同一服务器的不同端口:从a服务器的88端口请求a服务器的89端口,这是端口不同。 不同服务器之间的请求(就是域名不同):从a服务器向b服务器发送请求。 不同协议之间的请求:a服务器通信是http协议,b服务器是https协议,a向b发出请求,这是不同协议的跨域请求。 总之,只有相同协议,相同域名(包括一级域名,二级域名,三级域名),同一端口下的通信是可以畅通无阻的。如果它们之间有任何一个不同,那么通信就是跨域的,就会出现跨域问题。
跨域请求分析
如图从 http://www.salesys.com -> http://api.salesys.com/api/search/search/page 这就是一个跨域请求,如果没有进行相关配置,跨域请求是不能到达的,会出现: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://…’ is therefore not allowed access. 的错误信息。
解决跨域请求不能到达问题
这里引用的:https://www.ruanyifeng.com/blog/2016/04/cors.html 要解决跨域问题,主要就是让浏览器何服务器都支持跨源通信(Cross-origin resource sharing)。 目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
因此我们要解决跨域问题,只需要在我们的服务端进行相关配置,无需关注浏览器。 首先对于单个服务我们只需要在单个服务上添加相应的配置: 编写一个配置类: SaleSysCorsConfig .java(名字随意),但是必须在类上声明一个注解@Configuration,表明该类是一个配置类,在类中我们需要完成相应的操作(就是让服务支持CORS跨域通信): 1.创建CorsConfiguration对象 2.添加允许的域(就是允许哪些请求可以跨域访问我们的服务) 3.添加允许的请求方式,如GET,POST 4.返回
package com.xjitcm.CorsFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class SaleSysCorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://salesys.xjitcm.com");
config.addAllowedOrigin("http://api.salesys.com/api/auth/accredit");
config.addAllowedOrigin("http://www.salesys.com");
config.setAllowCredentials(true);
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
}
注意:单个服务就将配置文件写在对应的程序中,如果是多个服务,可以引入网关,将配置文件写在网关中。
|