记一次跨域问题的解决方案
来源:互联网 发布:传奇数据库 编辑:程序博客网 时间:2024/06/06 22:41
一、背景
在公司空暇时间,笔者使用 AngularJS + SSM 方案编写一套权限控制系统。由于采用的是前后端分离的思想,前端页面服务启动的端口和后端服务启动端口不一致导致请求跨域问题的出现。在此,写下解决问题的流程。
二、基础知识
2.1 什么是同源
URL 由协议、域名、端口和路径组成,如果两个 URL 的协议、域名和端口相同,则表示它们同源。
2.2 什么是同源策略
浏览器的同源策略,限制了来自不同源的 document 或脚本,对当前 document 读取或设置某些属性。其目的是为了保证用户信息的安全,防止恶意的网站窃取数据。
另外,同源策略只对网页的 HTML 文档做了限制,对加载的其他静态资源如 javascript、css、图片等仍然认为属于同源。
2.3 什么是跨域
跨域,指的是浏览器不能执行其他网站的脚本。同源策略规定,AJAX 请求只能发给同源的网址,否则就报错。
建议读者先浏览文章末尾提供的参考资料进一步了解跨域相关的内容,再结合本文案例思考和理解
三、解决案例
CORS 是一个 W3C 标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。
笔者采用 CORS 方案解决问题。
3.1 前端页面设置
3.1.1 设置请求参数
在 ajax 请求参数中添加 2 个参数设置:
xhrFields: { withCredentials: true }crossDomain: true
3.1.2 源码演示
$.ajaxSetup({dataType: "json",cache: false,xhrFields: { withCredentials: true },//设置后,请求会携带cookiecrossDomain: true,complete: function(xhr) {if (xhr.responseJSON) {if (xhr.responseJSON.code == 401) {layer.msg(xhr.responseJSON.msg);setTimeout(function() {window.location.href = "login.html";}, 1500);}} else {layer.msg(xhr.responseText);}}});
3.2 后端服务器设置
3.2.1 设置跨域请求过滤器
public class SimpleCORSFilter implements Filter {public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) resp;HttpServletRequest request=(HttpServletRequest)req;// 处理简单请求// 跨域请求默认不携带cookie,如果要携带cookie,需要设置下边2个响应头response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));// 必选,所有有效的跨域响应都必须包含这个请求头, 没有的话会导致跨域请求失败response.setHeader("Access-Control-Allow-Credentials", "true");//可选,此处设置为true,对应前端 xhr.withCredentials = true;//处理非简单请求// 非简单请求:浏览器会发送两个请求, 第一个请求(成为预检请求)会像服务器确定是否接受这个跨域请求, 第二个才是真正的发出请求. 浏览器自动的处理这两个请求, 同时预检请求也是可以被缓存的, 而不用每次请求都需要发送预检请求.// 预检请求是在实际的请求发出前先向服务器确认是否能够处理这个请求. 服务器应该检查上边两个请求头的值, 来判断这个请求是否有效.response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE");// 必选response.setHeader("Access-Control-Allow-Headers","Origin,No-Cache,X-Requested-With,If-Modified-Since," +"Pragma,Last-Modified,Cache-Control,Expires,Content-Type,X-E4M-With,userId,token");//response.setHeader("Access-Control-Max-Age", "0");// 可选,在每个请求前面都发送一个预检请求是很浪费资源的, 这个值允许你设置预检请求的缓存时间, 单位是秒.//response.setHeader("XDomainRequestAllowed","1");chain.doFilter(req,resp);}public void init(FilterConfig filterConfig) {}public void destroy() {}}
3.2.2 配置 web.xml 文件
<filter><filter-name>cors</filter-name><filter-class>com.light.system.web.filter.SimpleCORSFilter</filter-class></filter><filter-mapping><filter-name>cors</filter-name><url-pattern>/*</url-pattern></filter-mapping>
四、参考资料
- http://lleohao.com/2017/08/12/%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F/
- http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
- http://www.ruanyifeng.com/blog/2016/04/cors.html
阅读全文
0 0
- 记一次跨域问题的解决方案
- 记一次Spring MVC 一次请求,后台却访问两次的问题的解决方案
- 记一次js中和php中的字符串长度计算截取的终极问题和完美解决方案
- 记一次JSON到前台乱码的解决方案
- 关于前端跨域 一次动作 两次请求的问题
- 【Richie Zhu】android开发时使用Android模拟器经常遇到连不上、连一次掉一次等诸多问题的解决方案
- 记一次iphone 微信内置浏览器跨域无法获取cookie问题的解决方法
- 跨域问题的初级解决方案
- 关于跨域问题的解决方案
- AJAX的跨域问题CORS解决方案
- JavaScript跨域问题的解决方案
- 浏览器的跨域问题以及解决方案
- 跨域问题及其简单的解决方案
- 浏览器的跨域问题以及解决方案
- 浏览器的跨域问题以及解决方案
- 浏览器的跨域问题以及解决方案
- 浏览器的跨域问题以及解决方案
- 跨域问题的5种解决方案
- #include< >与 #include" "的区别
- 课堂练习3(第四周)
- 40-程序中内存布局
- java 判断字符串是否包含汉字的方法
- 数据结构_线性表_链表实现
- 记一次跨域问题的解决方案
- 浮动之QQ会员页面导航
- 【Spring】Spring+Struts2+Hibernate3整合(十七)
- 编译 库链接实例(动态库 隐式显式)
- 解决xcode打开时假死的问题
- NEUQ oj 1036 题解
- RadioGroup设置点击text的基本布局样本
- 使用tensorflow:LSTM神经网络预测股票(三)
- 感知机模型(原始形式和对偶形式)