服务器跨域
主流浏览器Chrome Edge FireFox Safari都会有域的保护,域(Domin)指的就是域名,关于域的知识请参考同源策略相关文章
如果出现了跨域,HTTP请求会提示错误
1 | XMLHttpRequest cannot load http://localhost:8080/all. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. |
提示 Access-Control-Allow-Origin 是null所以不允许接入,该字段是HTTP的一个Header字段
通常需要由服务器设定在返回报文中
对Response对象进行操作
第一种方法可以手动在返回方法的HttpServletResponse对象中手动设置 其中星号代表任意地址
1 | public static void setJSONResponse(HttpServletResponse response) { |
使用Servlet过滤器统一添加
写一个跨域请求过滤器
1 | public class CrossDominFilter implements Filter { |
在web.xml对Servlet添加过滤器
1 | <!--跨域开启过滤器--> |
跨域请求Set-Cookie和Cookie方法失效
在跨域请求中另一个问题,由于host不同,跨域请求无法触发服务器容器的Set-Cookie和Cookie机制,导致在登录时无法通过Session/Cookie机制验证是否是同一个用户的请求,需要服务器端和客户端同时修改才能完成该机制
服务器端修改
在验证可信后对跨域请求后进行Set-Cookie
Access-Control-Allow-Credentials 接受跨域请求携带的Cookie,在使用该字段的时候 Allow-Origin 不能为星号,必须为确定的值。指的注意的是 Allow-Origin 仅能设定一个值,如果想要设定多个则需要用Nginx进行处理,不能直接在Java中添加多个。
1 | public class CrossDominFilter implements Filter { |
有些文章中还包含一个字段 Access-Control-Allow-Headers 这个字段并不是必须的,仅当预请求中包含Access-Control-Request-Headers时,是必须包含的,这是对预请求当中Access-Control-Request-Headers的回复,和上面一样是以逗号分隔的列表,可以返回所有支持的头部。
浏览器客户端
发送才有可信凭证的Ajax请求,其中 xhrFields: {withCredentials: true} 是必须的,而crossDomain: true则不是,会带着Cookie去服务器。
1 | $.ajax(Constant.LOGIN_SIGN_IN, { |
跨域的数据安全性
跨域机制仅仅是浏览器的一种本地保护机制,在简单Ajax跨域中,在服务器未添加 Access-Control-Allow-Origin 时并不是代表着服务器未返回数据,而是浏览器没有接收,如果使用BurpSuit等工具截获Response报文,手动加入,则浏览器一样可以正常显示