目录
1、跨域的产生:
2、跨域产生的问题:
2.1简单请求与非简单请求的区别
3、为什么要对跨域进行特殊处理
3.1先来说说什么是源
3.2什么是同源策略?
3.3•不受同源策略限制的:
4如何解决跨域呢
4.1使用JSONP
4.2对请求头进行设置,通知浏览器可以请求
4.2.1设置CorsFilter
4.2.2当需要请求session数据的时候上面的设置会时session无效,也就是每次请求的sessionID不一致
withCredentials介绍:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/withCredentials
跨服务请求,及请求路径的协议、端口、域名任意一个不同就算跨域
如果不对跨域做处理,则通过AJAX请求不到目标服务的数据,或者请求到目标服务的数据,无法使用(请求到数据和请求不到数据的可参考简单请求和非简单请求https://www.cnblogs.com/renpingsheng/p/7688134.html)
* 请求方式:HEAD,GET,POST
* 请求头信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 对应的值是以下三个中的任意一个
application/x-www-form-urlencoded
multipart/form-data
text/plain
只有同时满足以上两个条件时,才是简单请求,否则为非简单请求
控制台异常:
这是浏览器的同源策略所导致参考https://baike.baidu.com/item/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5/3927875?fr=aladdin
• 源(origin)就是协议、域名和端口号。
以上url中的源就是:http://www.company.com:80
若地址里面的协议、域名和端口号均相同则属于同源。
以下是相对于 http://www.a.com/test/index.html 的同源检测
• http://www.a.com/dir/page.html ----成功
• http://www.child.a.com/test/index.html ----失败,域名不同
• https://www.a.com/test/index.html ----失败,协议不同
• http://www.a.com:8080/test/index.html ----失败,端口号不同
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。
页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的,,,
以上就是跨域的产生原因和过程
仅限get请求(原因参考https://blog.csdn.net/shuidinaozhongyan/article/details/78155693)
如下(由于代码是在内部环境开发,代码无法直接考出,这部分代码当时的查找地址竟然找不到了,将就下哈)
注释部分和下面的时两种设置,都可以
分两步:
后台的设置
如果要保证session一致,就不能将Origin设置为*号,必须设置成具体的请求地址,同时必须设置
Access-Control-Allow-Credentials为true
如何设置Origin呢,需要通过request获取,上面的代码显然不行,试过将request传递,但是报错了
所以可以通过自定义filter
代码如下(Springboot开发环境):
@Configuration
public class WebConfiguration {
@Bean
public RemoteIpFilter remoteIpFilter(){
return new RemoteIpFilter();
}
@Bean
public FilterRegistrationBean testFilterRegistration(){
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName","paramValue");
registration.setName("MyFilter");
registration.setOrder(1);
return registration;
}
public class MyFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) servletResponse;
HttpServletRequest req = (HttpServletRequest) servletRequest;
String origin = req.getHeader("Origin");
if (!org.springframework.util.StringUtils.isEmpty(origin)) {
//带cookie的时候,origin必须是全匹配,不能使用*
res.addHeader("Access-Control-Allow-Origin", origin);
}
res.addHeader("Access-Control-Allow-Methods", "*");
String headers = req.getHeader("Access-Control-Request-Headers");
// 支持所有自定义头
if (!org.springframework.util.StringUtils.isEmpty(headers)) {
res.addHeader("Access-Control-Allow-Headers", headers);
}
res.addHeader("Access-Control-Max-Age", "3600");
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true");
filterChain.doFilter(req, res);
}
@Override
public void destroy() {
}
}
}
前台设置:在请求中添加
两种请求方式:
$.ajax({
url:url,
//加上这句话
xhrFields: {
withCredentials: true
},
crossDomain: true,
success:function(result){
alert("test");
},
error:function(){
}
import axios from 'axios'
axios.defaults.withCredentials = true