前端是通过ajax发送请求,浏览器的ajax,是有同源策略的,如果违反了同源策略,就会产生跨域问题,
Zuul作为微服务的网关,在他上面处理跨域,也是一种选择,Zuul的跨域其实可以看成是Spring的跨域,
Spring的跨域常用的一种方法,是在服务被调用的类或者方法上,增加@CrossOrgin注解,来声明自己支持
跨域访问,这种方式的缺点其实挺明显的,他的作用域是在类或者方法上,你看我们这光应用就有好多个,
那一个应用里的类或者方法,就更加的多了,另外一种方法呢,是在Zuul里增加@CrosFilter过滤器,此方法
是增加在网关上,对内部的代码无任何改造
在Product项目里面,如果我们要对某个接口跨域的话,你要让他实现跨域,要怎么做呢,用@CrossOrigin这个注解,
@GetMapping("/list")
@CrossOrigin
public List<ProductInfo> list(HttpServletRequest request) {
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName + "========>" + headerValue);
}
//1. 查询所有在架的商品
List<ProductInfo> productInfoList = productService.findUpAll();
return productInfoList;
}
这个注解就可以实现对跨域访问了,我们看一下里面有哪些参数,这些参数没有什么问题,allowCredentials你设为true的话,
表示允许cookie跨域
/**
* Whether the browser should include any cookies associated with the
* domain of the request being annotated.
* <p>Set to {@code "false"} if such cookies should not included.
* An empty string ({@code ""}) means <em>undefined</em>.
* {@code "true"} means that the pre-flight response will include the header
* {@code Access-Control-Allow-Credentials=true}.
* <p>If undefined, credentials are allowed.
*/
String allowCredentials() default "";
值得注意的就是这个字段,其他的大家看看都知道,在某个项目Controller里面,如果要对单个接口进行跨域的话,
怎么来设置,那想跨域的接口特别多,我需要统一的来设置怎么做呢,这里新建一个配置,再建一个类,Cros是四个单词的
缩写 Cross Origin Resource Sharing
翻译成中外过来就是,跨域资源共享,其实这里就是要做一个配置,这里有一个现成的类,CorsFilter,注意这个包名,
是Spring框架里面的
org.springframework.web.filter.CorsFilter
只需要对这个类配置一下就好了,这里面需要配一个CorsConfigurationSource
org.springframework.web.cors.CorsConfigurationSource
我们使用UrlBasedCorsConfigurationSource这个
org.springframework.web.cors.UrlBasedCorsConfigurationSource
注意看包名,我们要把跨域的配置给他注册到source上面去,路径是哪些域名进行配置,我们可以设置为所有
source.registerCorsConfiguration("/**", buildConfig()); // 4
CorsConfiguration这里就是我们要配置的真正配置了,看一下哪些可以配置的,其实跟刚刚的注解其实是完全一样的,
第一个是否支持Cookie跨域
corsConfiguration.setAllowCredentials(true);
这个是放哪些原始域,他要放的是一个list
corsConfiguration.addAllowedOrigin("http://localhost:3030");
所有的话你就放一个星号,原始域你自己定义的域名就好,还有允许的头
corsConfiguration.addAllowedHeader("*"); // 2
也可以和上面一样,全部允许,还有方法,GET还是POST
corsConfiguration.addAllowedMethod("*"); // 3
允许所有的话就填星号,还有一个是缓存时间
corsConfiguration.setMaxAge(300L);
在这个时间段里,对于相同的跨域请求,他就不再进行一个检查了,比如你可以填个300秒,这就是在Zuul里面配置一个
跨域,因为跨域都是由前端JS发起,那么我们这个项目都在写后端,都在调试,跨域这块大家可以当做了解,因为处理
跨域的解决方案,不一定非得这么来做,有很多时候可以考虑在Nginx上解决,如果对跨域非常感兴趣的小伙伴,通用的
解决方案,我之前也了解跨域,也处理过跨域的一些问题
package com.learn.cloud.config;
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;
/**
* 跨域配置
* @author Leon.Sun
*
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 你需要跨域的地址 注意这里的 127.0.0.1 != localhost
// * 表示对所有的地址都可以访问
corsConfiguration.addAllowedOrigin("http://localhost:3030");
// 跨域的请求头
corsConfiguration.addAllowedHeader("*"); // 2
// 跨域的请求方法
corsConfiguration.addAllowedMethod("*"); // 3
//加上了这一句,大致意思是可以携带 cookie
//最终的结果是可以 在跨域请求的时候获取同一个 session
corsConfiguration.setAllowCredentials(true);
// corsConfiguration.setMaxAge(10L);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//配置 可以访问的地址
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}