前言
当项目前后分离时,就涉及到跨域问题,最近在用一个前端用vue,后端用springboot的项目,就学了一下跨域问题的解决方法,这里记一下笔记。什么是跨域,跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。解决方法有很多种,这里记录个人能够理解的几种。
具体方式
-
@CrossOrigin注解
Spring MVC提供了@CrossOrigin注解给方法或controller加注解@CrossOrigin(value="*",allowCredentials=“true”)
缺点:
<1>每次发送2次请求,第一次查看是否允许跨域请求,第二次发起get、post等请求。
<2>如果需要传递cookies,需要额外设置allowCredentials=“true”。
<3>为开发方便往往设置成" * ",导致所有域名都可以跨域请求。 -
nginx (engine x)反向代理
需要下载安装nginx软件,打开nginx目录下conf目录里面nginx.conf文件,配置文件内容,可以配置客户端跨域或服务端跨域,两种方式解决跨域问题,具体配置百度。
缺点:
<1>需要单独安装软件,服务器还好,开发时就不方便了。 -
springboot设置cors跨域
CORS(Cross-origin resource sharing-跨源资源共享)允许网页从其他域向浏览器请求额外的资源,例如字体,CSS或来自CDN的静态图像。 CORS有助于将来自多个域的网页内容提供给通常具有相同安全策略的浏览器。
有俩种解决方法
第一种:
public class CorsFilter extends OncePerRequestFilter {
static final String ORIGIN = "Origin";
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String origin = request.getHeader(ORIGIN);
response.setHeader("Access-Control-Allow-Origin", "*");//* or origin as u prefer
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "PUT, POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "content-type, authorization");
if (request.getMethod().equals("OPTIONS"))
response.setStatus(HttpServletResponse.SC_OK);
else
filterChain.doFilter(request, response);
}
}
@Bean
public CorsFilter corsFilter() throws Exception {
return new CorsFilter();
}
http
.addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
.headers()
.cacheControl();
第二种:
在springboot启动main类同级目录下创建一个配置类,如下:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
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 {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// config.setAllowedOriginPatterns(Collections.singletonList("*"));
// 设置你要允许的网站域名,如果全允许则设为 *
config.addAllowedOrigin("http://localhost:9527");
// 如果要限制 HEADER 或 METHOD 请自行更改
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// 这个顺序很重要哦,为避免麻烦请设置在最前
bean.setOrder(0);
return bean;
}
}
- springboot整合shiro解决跨域
maven导入
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
前后端分离跨域解决方案是采用CORS
//这里实不实现接口没有影响
@Configuration
public class WebConfig implements WebMvcConfigurer {
//解决跨域
@Bean
public CorsFilter corsFilter() {
CorsConfiguration conf = new CorsConfiguration();
conf.addAllowedHeader("*");
conf.addAllowedMethod("*");
conf.addAllowedOrigin("*");
//允许cookie
conf.setAllowCredentials(true);
conf.setMaxAge(3600L);
conf.addExposedHeader("set-cookie");
conf.addExposedHeader("access-control-allow-headers");
conf.addExposedHeader("access-control-allow-methods");
conf.addExposedHeader("access-control-allow-origin");
conf.addExposedHeader("access-control-max-age");
conf.addExposedHeader("X-Frame-Options");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", conf); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
这种方法具体没有实测,代码还不完整,具体用法百度。
后记
记录的这4中方法中,第1种和第3种的第二种方法亲测可用。