1.跨域的简介
当协议、域名、端口号任意一个不相同时,都算作不同域。不同域之间请求资源,就是跨域。
跨域并不是http请求发送不出去,请求可以发出去,服务端也能接受并正常返回结果,只是结果被浏览器拦截了。
当不同域访问,就会报以下错误:2.使用WebMvcConfigurerAdapter初始化参数
(1)使用@Bean注入的方式
添加@Configuration注解,配置Bean,具体使用如下:
@Configuration
public class Cors{
@SuppressWarnings("deprecation")
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
.allowCredentials(true).maxAge(3600);
}
};
}
(2)继承WebMvcConfigurerAdapter方法,覆写addCorsMappings方法,具体实现如下:
@Configuration
public class Cors extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
.allowCredentials(true).maxAge(3600);
}
}
3.使用拦截器的方法进行处理
拦截器的书写方法如下:
package com.example.demo.util.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if (request.getHeader(HttpHeaders.ORIGIN) != null)
{
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.addHeader("Access-Control-Max-Age", "3600");
}
return true;
}
/**
* 在业务处理器处理请求执行完成后,生成视图之前执行的动作
* 可在modelAndView中加入数据,比如当前时间
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
/**
* 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
* 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
使拦截器生效:
如同2方法,覆写的方法改为addInterceptors即可,如下:
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
return new WebMvcConfigurerAdapter() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CorsInterceptor());
}
};
}
4.使用过滤器的方法进行处理,过滤器的使用方法如下:
public class InitCORSFilter implements Filter{
private Logger logger = LoggerFactory.getLogger(InitCORSFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("==== 初始化系统允许跨域请求 ====");
}
/**
* 解决跨域:Access-Control-Allow-Origin,值为*表示服务器端允许任意Domain访问请求
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if(response instanceof HttpServletResponse) {
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
httpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with, sid, mycustom, smuser");
httpServletResponse.addHeader("Access-Control-Max-Age", "1800");//30 min
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("filter is destroy");
}
}
5.细粒度处理,即单个方法处理
(1)使用注解,在对应的方法上使用注解,如下:
@CrossOrigin(origins = "*")
@RequestMapping(value="/find/{id}/{name}")
public User find(@PathVariable int id, @PathVariable String name) {
User user = new User();
user.setId(id);
user.setName(name);
user.setDate(new Date());
return user;
}
添加HttpServletResponse,修改反应头文件,如下:
@RequestMapping(value="/find/{id}/{name}")
public User find(@PathVariable int id, @PathVariable String name, HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.addHeader("Access-Control-Max-Age", "3600");
User user = new User();
user.setId(id);
user.setName(name);
user.setDate(new Date());
return user;
}
经测试,以上方法均可解决跨域问题。