说明:
(1)本篇博客内容:使用CorsFilter过滤器,在Spring Boot上解决跨域问题;
(2)声明:自己在本机部署前端项目后,因为我们已经在前端文件中设置了域名;
所以,通过【自己在本机部署的前端项目】去访问【自己在本机部署的后端项目的,接口】时,需要石红SwitchHosts开启虚拟域名绑定,否则就会出现访问不到的情况;
(3)PS:经过多次正确情况和错误情况的,测试验证;本篇博客讲到的内容,可以确保都是OK的;
目录
零:以前介绍过【浏览器的同源策略】(也就是跨域访问的问题);
一:【部署在一个地方的,前端】在访问【部署在另一个地方的,后端的,发送短信接口】时,跨域访问问题,演示;
二:实现跨域访问:使用【CorsFilter过滤器】的策略,来解决;
1.在【imooc-news-dev-api】接口工程中,创建一个配置类:CorsConfig类(其就是一个“返回CorsFilter过滤器对象”的类);
(1)在【RESTful开发风格7:跨域问题一:浏览器同源策略;】中介绍过浏览器的同源策略,介绍了浏览器同源策略带来的“障碍”;
(2)在【RESTful开发风格8:跨域问题二:Spring MVC实现“CORS跨域访问”的两种策略:类上使用【@CrossOrigin注解】;配置文件中通过<mvc:cors>进行全局配置;】,介绍过在Spring MVC项目中,如何进行跨域访问;
1.演示前提;
我们在【6:第二章:架构后端项目:2:使用Tomcat运行一下前端项目,先看看前端的内容;】中,把基础部分的前端内容,已经copy到本机Tomcat的webApp目录下;
同时,在【7:第二章:架构后端项目:3:虚拟域名的绑定与使用;(使用SwitchHosts,给项目配置虚拟域名)】中,我们也已经修改了前端项目中app.js中映射端口和url,以让其符合自己设置的、后端的端口号等;
2.触犯浏览器同源策略,演示;
所以,我们开启本机的Tomcat;然后,访问【http://localhost:8080/imooc-news/writer/passport.html】,直接点击【发送验证码】按钮,调用后端的【发送短信,接口】,其是会触犯浏览器的同源策略的,也就是跨域访问的问题;
说明:
(1)因为我们的前端的“域”和后端的“域”是不同的,所以其会触犯浏览器的同源策略,导致无法访问;
PS:当我们使用浏览器的时候,才会有同源策略带来的问题;;;如果,我们使用的是小程序、ISO或者安卓,即只要其不是浏览器,就不会有同源策略,自然也就不会有相应的问题;(但是,对于这个“结论”,不要绝对;如果使用H5等,还是可能存在不同的;;;暂时没有深究)
PS:统一的一些配置类,我们会将其放在【imooc-news-dev-api】接口工程中;比如,Swagger2我们就放在了【imooc-news-dev-api】接口工程中;;;所以,这儿的配置类,我们也写在了【imooc-news-dev-api】接口工程中;
1.在【imooc-news-dev-api】接口工程中,创建一个配置类:CorsConfig类(其就是一个“返回CorsFilter过滤器对象”的类);
CorsConfig类:
package com.imooc.api.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; /** * 工具类: */ @Configuration public class CorsConfig { public CorsConfig() { } @Bean public CorsFilter corsFilter() { // 1. 添加cors配置信息 CorsConfiguration config = new CorsConfiguration(); //添加【允许访问我们后端程序的,域】;;这儿的*的意思是,我们后端部署后,任何域都可以访问; // PS:实际项目中,一定不要这么干;;;在实际开发中,究竟有哪些域可以访问我们的程序,一般是由严格规定的; config.addAllowedOrigin("*"); // 设置是否发送cookie信息 config.setAllowCredentials(true); // 设置允许请求的方式 config.addAllowedMethod("*"); // 设置允许的header config.addAllowedHeader("*"); // 2. 为url添加映射路径 UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource(); corsSource.registerCorsConfiguration("/**", config); // 3. 返回重新定义好的corsSource return new CorsFilter(corsSource); } }说明:
(1)这儿就是使用【Java Config的方式】,把CorsFilter对象实例化进IoC容器;;;可以参考【Spring IoC容器与Bean管理25:使用Java Config方式实现Spring IoC一:对象实例化;(@Configuration,@Bean)】;
(2)有关CorsFilter过滤器的内容,可以参考【待写……】;
(3)说白了,这儿是通过过滤器的方式,通过处理请求与响应,来解决这个问题;而且,对于CorsFilter类,往上追查,能看到其是实现了javax.servlet的Filter接口的;
● 有关【J2EE中的过滤器】、【Spring 中的AOP】、【Spring MVC中的拦截器】的区别,可以参考【附加:【J2EE中的过滤器】、【Spring 中的AOP】、【Spring MVC中的拦截器】的区别;(不要看,没写完……)】;
(4)一个不清楚的点:如果后端是通过Nginx做的反向代理,那么我们就可以直接在网关中设置跨域;;;只是,我们这儿没有使用Nginx,所以这儿我们把“跨域的解决方式”放在了Spring boot中;
(5)声明:在实际项目中,后端程序究竟对那些外部域开启访问,都是严格规定的;本篇博客直接设为了*;在实际中,要根据项目和公司规定,谨慎设置;
2.效果;
1.先全局install一下整个项目;
……………………………………………………
2.然后,启动【user】的主启动类;
……………………………………………………
3.然后,访问【user】的【发送短信,接口】;
经过多次检查,还是不行~~~:
盲猜,是自己前端的问题,前端在点击【发送验证码】按钮后,其请求地址并不是我们这个接口的实际地址;
此时,就感觉到,自己没有开启本机安装的SwitchHosts,没有进行虚拟域名的绑定哎;于是,自己就开启SwitchHosts,去绑定虚拟域名,以让【http:/user.imoocnews.com:8003/passport/getSMSCode?mobile=18888888888】能够指向【本机的发送短信接口的实际地址,http:/localhost:8003/passport/getSMSCode?mobile=18888888888】;(否则,如果不绑定的话,【http:/user.imoocnews.com:8003/passport/getSMSCode?mobile=18888888888】就是一个找不到的域名,,,不过,好像如果一个地址找不到,报的不应该是跨域问题啊,,,算了,就这么地吧~~~)
然后再次调用:发现其可以访问了;而且,响应头中也有了【Access-Control-Allow-*】这些东西,这说明,我们的后端程序开启了跨域访问;