因为浏览器处于安全考虑,有同源策略。换句话说,如果协议、域名或者端口有一个不同的话就是跨域。由于Ajax只能获取同源的资源,因此Ajax请求会失败。
下面我们就来总结一下跨域方式有哪一些:
原理:Web页面上调用js文件不受跨域影响,凡是具有src属性标签都不受同源策略的影响,正是因为这个特性,我们把资源放到script标签中,src属性的格式是”url+参数”,比如url?cd=doJSON,cd是我们和后台协商好的类似于形参的东西,是一个留给我们写处理函数接口,doJSON就是我们事先定义好的函数,也就是回调函数,所有数据会以参数的形式传递给该函数(json是一种数据格式,jsonp是一种约定俗成的非正式传输协议)。
注意:JSONP使用简单且兼容老版本浏览器,但是只限于get请求。
为什么不支持post请求?因为jsonp的方式原理上和``是一致的,因为它原理实际上就是使用js的script标签进行传参,那么必然是get方式了,和浏览器中敲入一个url是一样的。
原理:需要浏览器和后端同时支持。要在服务器端的response header里面加一个Access-Control-Allow-Origin:指定域名||* (表示所有域名都可以跨域),浏览器端便可以发起post的跨域请求。浏览器会自动进行CORS通信,实现CORS通信的关键是后端。只要后端实现了CORS,就实现了跨域。
IE8和IE9需要通过XDomainRequest来实现。它实现了CORS的部分规范,只支持GET/POST形式的请求。在服务器端,依旧要求在响应报头添加”Access-Control-Allow-Methods”标签(这点跟CORS一致)。创建一个XDomainRequest的实例,调用open()方法,再调用send()方法,请求返回之后,会触发load事件,相应的数据也会保存在responseText属性中。
前提条件:这两个域名必须属于同一个基础域名,而且所有的协议、端口都要一致,否则无法利用document.domain进行跨域。
比如:a.test.com和b.test.com(它们服务器域名不同,但是拥有相同的上级域名test.com)适用于该方法。只需要给页面添加document.domain=’test.com’表示二级域名都相同就可以实现跨域了。
document.domain是用来得到当前网页的域名,可以赋成当前域名或者基础域名。
document.domain="xxx.com"
。需要注意:一个网页被攻击,另外一个站点就会引起安全漏洞。
h5中有一个功能就是跨文档消息传输。getMessageHTML.postMEssage(message,targetOrigin);
getMessageHTML是接受信息的页面引用,可以是iframe的contentWindow,window.open的返回值;
targetOrigin是用于限制getMessageHTML的,填* 的时候不做限制。
服务器不受同源策略的影响,把所有资源放在服务器上,然后让服务器上的网页获取这些资源。
1 | // 发送消息端 |
iframe+location.hash
缺点:数据直接暴露在url中,并且数据长度和类型都有限制。
iframe+window.name
缺点:需要借助同源其他子页面。