-
总的来说, 跨域问题有3个原因: 浏览器的限制, 跨域, xhr(XMLHttpRequest) 请求; 这三个条件同时满足才会产生跨域安全问题
浏览器的限制
发生这个跨域问题不是因为后台不允许前台调用, 真正的原因是浏览器出于安全考虑, 当他发现你的请求是跨域的时候, 会对发送的请求进行校验, 如果校验不通过, 就会报跨域错误. 这个时候可能你的请求已经发送成功并且返回了数据, 但控制台报了一条跨域错误, 说明服务器后台式没有任何限制的, 是浏览器报的错; 说白了就是浏览器多管闲事, 而不是后台不允许
2. 跨域:发出去的请求不是本域的. 请求里面 协议, 域名, 端口任何一个不一样, 浏览器都会认为是跨域; 比如前台是localhost:8080端口, 请求的是localhost:8081端口 , 虽然域名相同, 但端口不一样, 所以跨域了
3. 发送的是 XHR(XMLHttpRequest) 请求 (也是最重要的原因); 只要发送的不是XHR请求, 比如jsonp请求, 就算是跨域, 浏览器也不会报跨域问题
查看全部 -
我想说在这里的故事将会是怎么样,但是并不是我们所需要的。
查看全部 -
由控制台可以看到,Console 报了一个错误,这就是跨域访问安全问题
查看全部 -
创建Springboot工程,并编写后台服务代码查看全部
-
哈哈哈哈查看全部
-
nginx实现隐藏跨域: 在下面的a.com.conf文件中配置参数后,在前端代码中把请求http://localhost:8081/test地址改成代理地址/ajaxserver
nginx反向代理配置:
支持跨域与隐藏跨域的区别:
支持跨域:调用的url地址都是绝对地址
隐藏跨域:调用的url都是本域的,是相对地址,
查看全部 -
String 框架解决方案: @CrossOrigin 注解,可以在 Controller 上,也可以在 方法上,还可以进行细节配置。
属于服务端改动的一种。
查看全部 -
带自定义头的跨域:
1. ajax示例代码:
2. 请求头信息
3. 再次请求将会报如下错误信息:
解决办法:
res.addHeader("Access-Control-Allow-Headers", "Content-Type,x-header1,x-header2");
这种方式把请求头写死了,不推荐
4. 支持所有跨域,示例代码:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String origin = req.getHeader("Origin"); //res.addHeader("Access-Control-Allow-Origin", "*"); //允许所有的域跨域 //res.addHeader("Access-Control-Allow-Methods", "*"); //允许所有的方法跨域 if(!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(!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"); chain.doFilter(request, response); }
查看全部 -
当产生跨域的时候,请求头中会多一个字段,叫做origin,这个字段有当前域的信息。所以在发送带cookie的请求,后台又不知道调用方的域的信息时,可以先取到请求头中origin字段的值再赋值给响应头的access-control-allow-origin字段中。
带Cookie的跨域: 1. "Access-Control-Allow-Credentials","true" 2. Access-Control-Allow-Origin 不能为* ,必须为【调用方】的域名+端口 3. 发送的Cookie是【被调用方】的cookie
查看全部 -
一、http会话session依赖于cookie, sessionid存放在cookie中。
二、ajax
1、$.ajax({
type: "get",
xhrFields: {
widthCredentials: true // 发送ajax请求的时候会带上cookie
}
})
2、cookie是加在被调用方。
服务端就是被调用方,而客户端就是调用方。在浏览器的控制台中通过document.cookie="" 来设置cookie。
3、读cookie只能读到本域的。
4、带cookie时,后台代码注意以下2点:
(1)带cookie的时候,Access-Control-Allow-Origin,必须是全匹配,如http://localhost:8081, 不能是 *,否则报错,如下:
(2)带cookie进行跨域时,需要设置以下请求头:
res.addHeader("Access-Control-Allow-Credentials", "true")
查看全部 -
我们知道非简单请求, 每次会发出两次请求, 这会影响性能. HTTP协议增加了个响应头, 可以让我们在服务端设置`Access-Control-Max-Age`来缓存预检请求, 比如说我们可以设置为3600m, 也就是一小时客户端只会在第一次的时候发送两个请求, 接下来一个小时内`OPTIONS`请求就被缓存起来了.
查看全部 -
问题1:浏览器是先执行请求还是先判断跨域?
浏览器请求-->判断响应中是否有允许跨域-->发现不允许跨域,阻止跨域
说明:当执行跨域请求时,浏览器会提示当前接口不被允许,这说明浏览器已发出了当前请求,但是它的的响应内容被拦截;如果在Response header中的Access-Control-Allow-Origin设置的允许访问源不包含当前源,则拒绝数据返回给当前源。
当浏览器要发送跨域请求时,如果请求是复杂请求,浏览器会先发送一个options预检命令即一个options请求,当该请求通过时才会再发送真正的请求。
该option请求会根据请求的信息去询问服务端支不支持该请求。比如发送的数据是json类型(通过content-type设置)的话,会携带一个请求头Access-Control-Request-Headers: content-type去询问支不支持该数据类型,如果支持,则请求就会通过,并发送真正的请求
查看全部 -
简单请求和非简单请求
1.简单请求是先请求,浏览器再判断是否是跨域;而非简单请求要先发送一个预检命令,检查通过之后才会真正的把跨域请求发出去
2.非简单请求常见的是发送json格式的请求,如图contentType为“application/json;charset=utf-8”
最后的结果如下,返回了两个请求,一个是OPTIONS,另一个是POST请求,其中的OPTIONS就是一个预检命令,成功了之后才会发送后面的跨域请求
3.预检命令的缓存。因为这种非简单请求每次都会发送两次请求,其实效率是比较低的,但是如果能缓存预检命令的话,会响应的提高效率
在服务器中,添加一个响应头信息,告诉浏览器在截下来的一个小时可以缓存信息,就不需要再发送预检命令
查看全部 -
被调用方——Filter解决方案:
1. 浏览器是先执行后判断
2. 跨域请求和普通请求的区别:
跨域请求的请求头中多了一条信息:如下
origin : http://localhost:8081
这个值是当前请求的域名信息,如果 浏览器发现当前请求是跨域的时候,它就会在当前请求头中添加一个当前域的信息的字段;然后在请求返回的时候,它会检查响应头里面有没有允许跨域的信息存在,如果没有,它就会报错。
查看全部 -
被调用方解决——支持跨域
查看全部
举报