Cors跨域问题学习
最近做项目的时候因为前后端分离避不开跨域,之前都是含糊的就能使了,也没有过多去深入,今儿下定决心学一学。
学习用的文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
通篇看完文章,开始一点点的尝试,所写的例子均基于文档示例
案例一 简单请求
前端代码:
<!DOCTYPE html>
<html>
<head></head>
<body>
<script>
var invocation = new XMLHttpRequest();
var url = 'http://localhost:8080';
var handler;
function callOtherDomain(){
if(invocation)
{
invocation.open('GET', url, true);
invocation.onreadystatechange = handler;
invocation.send();
}
}
callOtherDomain();
</script>
</body>
</html>
如果利用文档给的代码,会报handler找不到的错,本人萌新一枚也不知道handler是啥,于是就在上面定义了一下,下文不在赘述。
java代码:
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;
/**
* @ClassName WebMvcConfig
* @Description TODO
* @Author AlvinZheng
* @Date 2020/7/14 17:26
* @Version 1.0
**/
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
source.registerCorsConfiguration("/**",config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
这里是基于spring boot的情况下,下文不在赘述。
结果:
成功!但是这和例子里的有点不同的是红框中的部分,例子里是有值得,但是我的没有,我测试了别的路径还是没有,我不明白了,此处待研究
案例二 预检请求
废话不多说上代码
前端代码:
<!DOCTYPE html>
<html>
<head></head>
<body>
<script>
var invocation = new XMLHttpRequest();
var url = 'http://localhost:8080';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
var handler;
function callOtherDomain(){
if(invocation)
{
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.onreadystatechange = handler;
invocation.send(body);
}
}
callOtherDomain();
</script>
</body>
</html>
java代码:
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;
/**
* @ClassName WebMvcConfig
* @Description TODO
* @Author AlvinZheng
* @Date 2020/7/14 17:26
* @Version 1.0
**/
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
//config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("X-PINGOTHER,Content-Type");
config.addAllowedMethod("POST,GET,OPTIONS");
source.registerCorsConfiguration("/**",config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
结果:
有问题图就不放了,这里我发现报错了,报了跨域问题
经过百度搜索,发现了盲点,先上代码
/**
* @ClassName WebMvcConfig
* @Description TODO
* @Author AlvinZheng
* @Date 2020/7/14 17:26
* @Version 1.0
**/
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
//config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:8080");
config.addAllowedOrigin("null");
config.addAllowedHeader("X-PINGOTHER");
config.addAllowedHeader("Content-Type");
config.addAllowedMethod("POST");
config.addAllowedMethod("GET");
config.addAllowedMethod("OPTIONS");
source.registerCorsConfiguration("/**",config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
结果:
这时候回过头去看看两个java代码有什么不对么?
没错!第一个多了好几个add方法,这是因为,阅读源码发现貌似没有通过逗号分隔的这种做法。第二就是在addOrigin中多了个null,为什么要加这个框呢,还记得上个案例中红框框中的orgin么,你应该猜到了,这个地方写这null(笑哭),然后就可以了。
案例三 附带身份凭证的请求
在这里我们要使用cookies
前端代码:
java代码:
这里就用上面的代码了,重点在画横线的部分。
到这里根据文档的学习也就差不多了,但是一直有个问题我一直存在,为什么origin可以为null,但是文档里都是有具体的值的,我下翻发现文档对于origin的解释
注意黄框,说明是可以为null的,于是我百度了下,发现了这么一篇文章
http://blog.sina.com.cn/s/blog_625f850801015tik.html
貌似和csrf有关,这就明白了,至此基本上是理解了cors,后面等着我不断的实践了。