SpringBoot2.X开启跨域配置
什么是浏览器跨域
- 跨域:浏览器同源策略 1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。 最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"
协议相同 http https
域名相同 www.xdclass.net
端口相同 80 81
一句话:浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
浏览器控制台跨域提示:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
- 解决方法
1)JSONP
2)Http响应头配置允许跨域
nginx层配置 https://www.cnblogs.com/hawk-whu/p/6725699.html
3)程序代码中处理 SpringBoot 通过拦截器配置
//表示接受任意域名的请求,也可以指定域名
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
//该字段可选,是个布尔值,表示是否可以携带cookie
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
- options请求,这个需要注意
- 注意点: 假如接口报错,则跨域配置可能不生效(报错建议断点调试,排除异常错误)
示例代码
src/main/java/net/xdclass/online_xdclass/interceptor/CorsInterceptor.java
package net.xdclass.online_xdclass.interceptor;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//表示接受任意域名的请求,也可以指定域名
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
//该字段可选,是个布尔值,表示是否可以携带cookie
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
//这里可以不加,但是其他语言开发的话记得处理options请求
/**
* 非简单请求是对那种对服务器有特殊要求的请求,
* 比如请求方式是PUT或者DELETE,或者Content-Type字段类型是application/json。
* 都会在正式通信之前,增加一次HTTP请求,称之为预检。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,
* 服务器允许之后,浏览器会发出正式的XMLHttpRequest请求
*/
if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){
return true;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
注册跨域拦截器
src/main/java/net/xdclass/online_xdclass/config/InterceptorConfig.java
package net.xdclass.online_xdclass.config;
import net.xdclass.online_xdclass.interceptor.CorsInterceptor;
import net.xdclass.online_xdclass.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 拦截器配置
*
* 不用权限可以访问url /api/v1/pub/
* 要登录可以访问url /api/v1/pri/
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
@Bean
CorsInterceptor corsInterceptor(){
return new CorsInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 拦截全部路径,这个跨域需要放在最上面
*/
registry.addInterceptor(corsInterceptor()).addPathPatterns("/**");
registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/v1/pri/*/*/**")
//不拦截哪些路径 斜杠一定要加
.excludePathPatterns("/api/v1/pri/user/login","/api/v1/pri/user/register");
WebMvcConfigurer.super.addInterceptors(registry);
}
}