携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
大家好! 我是慕歌,一只想教你学习 Spring Boot的野生coder! 欢迎来到慕歌的 Sping boot系列教程,希望通过这个教程带大家搭建基础的 Spring Boot项目,该教程所有知识点均来源于本人的真实开发!
前言
在前一节的学习中,慕歌将自己长期使用的异常处理工具类交给了小伙伴们,相信认真看过前一篇内容的小伙伴们一定是收获颇丰。优雅的结果集返回,优雅的异常处理,两篇文章覆盖了90% 后端与前端的交互场景,续学会它们,就再也不用担心于前端数据交流不畅了!但是在真实的与前端交互中,可能还会出现其他问题,跨域问题,我相信是很多新手都会遇到的问题。那么这一节,慕歌就带大家从后端的角度,解析解决跨域问题!
引入:
跨域只会出现在spring boot web项目中,需要使用spring boot 的web 依赖。
<!-- web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
跨域:
那么跨域是怎麽产生的:
出于浏览器的同源策略限制,同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
什么是跨域:
当我们通过两种不同的协议访问:当前访问 :www.test.com/而实际访问时使用了另一种协议就导致www.test.com/index.html产生了跨域
跨域解决:
服务端会发送两次请求,第一次会发送预检请求,用于探测请求是否跨域,我们需要在服务端允许跨域请求的发送。那么解决方案有哪些呢,这里推荐几种在spring boot中的配置:
注解配置:可在需要进行跨域请求的位置添加此注解,该请求就可允许被跨域访问。对于小的项目,接口数量少,或者是对跨域有特殊需求可选择该方式。
@CrossOrigin注解
nginx代理:
nginx服务器具有反向代理的功能,可通过配置nginx服务,让所有服务有nginx服务器代理,nginx服务器允许跨域请求访问,所有请求经过nginx后映射真实的请求,就能够解决跨域问题。配置如下,可根据自己的服务名,服务端口进行修改:
// proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods GET, POST, OPTIONS;
add_header Access-Control-Allow-Headers *;
}
}
后端配置:
spring boot集合了 spring mvc的接口,能够对请求进行处理分发,所以如果我们在请求的接口处进行配置,允许请求跨域请求,那么跨域问题也能得到解决。配置如下,不同的spring boot 版本接口可能有差异,根据直接的spring boot 版本进行配置:
//请求跨域
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET","POST","PUT","HEAD","OPTIONS")
.allowCredentials(true)
.allowedHeaders("*")
.maxAge(3600);
}
spring boot同样支持注入跨域配置,进行自动配置,定义跨域请求类,通过跨域过滤器加入配置。
@Configuration
public class CretCorsConfiguration{
/**
* 允许跨域调用的过滤器
*/
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
//允许所有域名进行跨域调用
config.addAllowedOrigin("*");
//允许跨越发送cookie
config.setAllowCredentials(true);
//放行全部原始头信息
config.addAllowedHeader("*");
//允许所有请求方法跨域调用
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
// @Bean
// public CorsWebFilter corsWebFilter() {
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// // 配置跨域
// CorsConfiguration corsConfiguration = new CorsConfiguration();
// // 允许哪个请求头
// corsConfiguration.addAllowedHeader("*");
// // 允许哪个方法进行跨域
// corsConfiguration.addAllowedMethod("*");
// // 允许哪个请求来源进行跨域
//// corsConfiguration.addAllowedOrigin("*");
// corsConfiguration.addAllowedOriginPattern("*");
// // 是否允许携带cookie进行跨域
// corsConfiguration.setAllowCredentials(true);
//
// source.registerCorsConfiguration("/**",corsConfiguration);
// return new CorsWebFilter(source);
// }
}
结语
这一章的分享到这里就结束了,下一节中还将带来华为云短信服务的分享!
如果您觉得本文不错,欢迎点赞支持,您的关注是我坚持的动力!