1.什么是跨域
跨域是指一个域下的文档或者脚本企图去请求另一个域下的资源。
广义的跨域包括
(1)资源跳转:a,link,重定向,表单的提交
(2)资源嵌入:<link>,<img/>,<script>,background:url()
(3)脚本请求:js发起的ajax请求,dom和js对象的跨域操作
我们平时所说的跨域是浏览器同源策略发起请求的一种限制
同源策略
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
跨域的解决方案
1.通过JSONP跨域
通常为了减轻web服务器的负载,把js,img,css等静态资源独立分离到另一台独立域名的服务器上,在html页面中再通过响应的标签从不同域名下加载静态资源而被浏览器允许,基于此原理,我们可以动态创建script,再请求一个带参网址实现跨域通信。
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
2.CORS跨域资源共享
只需要服务端设置Access-Control-Allow-Origin即可,如果要携带cookie请求,前后端都需要设置.
前端设置:
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端设置是否带cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
服务器端设置:
// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");
// 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
response.setHeader("Access-Control-Allow-Credentials", "true");
// 提示OPTIONS预检时,后端需要设置的两个常用自定义头
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
3.postMessage跨域
postMessage是为数不多的可以跨域操作的window属性之一
用法:postMessage(data,origin)
data:传送的数据(一般使用JSON.stringfy(data))
origin:协议+主机+端口号