1 浏览器跨域问题
跨域请求,是一个站点访问另外一个不同域名站点上的资源。当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。比如说通过link标签加载外部样式表文件、通过img标签加载外部图片、通过script标签加载外部脚本文件等。
同源策略(Same origin policy)是浏览器最基本的安全功能,同源策略阻止一个域的javascript脚本和另外一个域的内容进行交互(带src属性的标签不受同源策略限制)。默认情况下,脚本访问文档属性等数据采用的是同源策略。出于安全考虑,Firefox、Chrome等很多浏览器都不允许跨域请求。
2 解决方法——CORS(推荐)
2.1 CORS 跨域资源共享
CORS (Cross-Origin Resource Sharing)是一个W3标准,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。CORS需要浏览器和服务器同时支持,CORS背后的基本思想,是使用HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。。实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信。CORS与JSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求,CORS支持所有类型的HTTP请求。
2.2 Java后端实现CORS跨域请求的方式:
使用注解 @CrossOrigin
重写 WebMvcConfigurer
返回新的CorsFilter
手动设置响应头 (HttpServletResponse)
自定web filter 实现跨域
无论哪种方案,最终目的都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域。
这里介绍Springboot常用的2种方法:
2.2.1 使用注解 (局部跨域)
在控制器类上使用注解 @CrossOrigin 表示该类的所有方法允许跨域。
@RestController
@CrossOrigin(origins = *)
public class HelloController {
@RequestMapping(/hello)
public String hello() {
return hello world;
}
}
2.2.2 拦截器(全局跨域)
@Configuration
public class CORSConfig {
@SuppressWarnings({ rawtypes })
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin(*);
config.addAllowedHeader(*);
config.addAllowedMethod(*);
source.registerCorsConfiguration(/**, config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
3 其它跨域方法
JSONP
proxy
window.postMessage
window.name
document.domain
webSocket