博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
记一次跨域问题的解决方案
阅读量:5906 次
发布时间:2019-06-19

本文共 2867 字,大约阅读时间需要 9 分钟。

原文地址:

博客地址:

一、背景

在公司空暇时间,笔者使用 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 },//设置后,请求会携带cookie    crossDomain: 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 文件

cors
com.light.system.web.filter.SimpleCORSFilter
cors
/*
复制代码

四、参考资料

转载地址:http://gecpx.baihongyu.com/

你可能感兴趣的文章
com.atlassian.util.concurrent.LazyReference$InitializationException: java.lang.NullPointerException
查看>>
ECSHOP_修改后台登陆路径
查看>>
Eclipse 3.7如何安装egit
查看>>
Android之最简单的ImageView加边框方法
查看>>
Redis 基础入门
查看>>
GTK中设置滚动条到某一特定位置
查看>>
算法(第四版)课后练习 1.3.29
查看>>
android Draw Rect 坐标图示
查看>>
What is Serverless?
查看>>
CYQ.Data 轻量数据层之路 应用示例三 Aop切入留言系统--操作日志(二十七)
查看>>
Homebrew 的安装方法(官方的方法老是安装失败) 第三方
查看>>
java 服务程序cpu资源占用高的问题
查看>>
Java程序员到架构师的推荐阅读书籍
查看>>
Centos6下DRBD的安装配置
查看>>
高流量站点NGINX与PHP-fpm配置优化
查看>>
Matplotlib Tutorial
查看>>
php5.6升级到php7.1.10(Linux环境)
查看>>
软件评估--你的软件,更重要的是你
查看>>
SVN 操作
查看>>
像素级质量 快速切页面工具
查看>>