什么是跨域?
是指一个资源去访问另一个不同协议或不同域名或同域名不同端口号是会发出跨域请求,跨域是指浏览器不能执行其他网站的脚本,是由浏览器的同源策略造成的,是浏览器对js施加的安全限制
为什么会出现跨域问题?
因为同源策略,所谓同源就是一种安全限制,它要求浏览器发出的请求的协议,域名,端口号必须要和ajax请求路径的协议,域名,端口号相同才能成功发起请求即成功访问到服务器;协议、域名、端口号都相同才会满足同源策略,三者中只要有一个不一样就是存在跨域问题。
解决:
Jsonp
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个<script>元素
,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
$.ajax({ url: 'http://www.test.com:8080/login', type: 'get', dataType: 'jsonp', // 请求方式为jsonp jsonpCallback: "handleCallback", // 自定义回调函数名 data: {} });
cors
CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
a.普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
b.带cookie跨域请求:前后端都需要进行设置
//告诉浏览器允许所有的域访问 //注意 * 不能满足带有cookie的访问,Origin 必须是全匹配 //resp.addHeader("Access-Control-Allow-Origin", "*"); //解决办法通过获取Origin请求头来动态设置 String origin = request.getHeader("Origin"); if (StringUtils.hasText(origin)) { resp.addHeader("Access-Control-Allow-Origin", origin); } //允许带有cookie访问 resp.addHeader("Access-Control-Allow-Credentials", "true"); //告诉浏览器允许跨域访问的方法 resp.addHeader("Access-Control-Allow-Methods", "*"); //告诉浏览器允许带有Content-Type,header1,header2头的请求访问 //resp.addHeader("Access-Control-Allow-Headers", "Content-Type,header1,header2"); //设置支持所有的自定义请求头 String headers = request.getHeader("Access-Control-Request-Headers"); if (StringUtils.hasText(headers)){ resp.addHeader("Access-Control-Allow-Headers", headers); } //告诉浏览器缓存OPTIONS预检请求1小时,避免非简单请求每次发送预检请求,提升性能 resp.addHeader("Access-Control-Max-Age", "3600");
【前端设置】根据xhr.withCredentials字段判断是否带有cookie
$.ajax({ url: 'http://www.test.com:8080/login', type: 'get', data: {}, xhrFields: { withCredentials: true // 前端设置是否带cookie }, crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie });
通过ngnix解决跨域问题
设置反向代理服务器
也就是在前端开启一个服务器,前端页面代码逻辑先跟代理服务器交互,然后再代理服务器与服务端的服务器进行交互,这样是两台服务器进行交互就不会存在跨域问题,因为跨域问题是浏览器向服务器发送请求时才会发生的问题