当前位置: 首页 > Web前端 > HTML

前端跨域总结

时间:2023-04-02 18:28:33 HTML

1.跨域的定义只要协议、域名、端口有任何不同,就会被认为是不同的域。如果从A域名访问B域名上的资源,就称为跨域。我们来看看几种跨域的方法:2.document.domain浏览器的同源策略有一些限制。第一,无法通过ajax方式请求不同来源的资源;第二,浏览器中不同域框架之间没有JS交互。如果有一个页面A,地址是http://www.domain.cn/A.html,这个页面有一个iframe,它的地址是http://domain.cn/B.html,显然是A和B是在不同的域,所以我们无法通过JS访问iframe中的数据和方法。这种情况可以用document.domain来解决。解决方法是将http://www.domain.cn/A.html和http://domain.cn/B.html的document.domain设置为同一个域名。需要注意的是,我们只能设置文档。域设置为自己或上级父域,主域必须相同。在A中,我们设置document.domain:在页面B中,我们还设置了document.domain但是这种方式只适用于不同子域的frame之间的交互。3.location.hash在有iframe的页面中,父窗口可以读写iframe的url,iframe也可以读写父窗口的url。URL中有#加后面字符的部分可以用来做锚点定位,这部分就是hash。可以通过修改URL的hash部分来进行双向通信,从而达到跨域的目的。每个窗口通过改变其他窗口的位置来发送消息,其他窗口通过监听URL改变事件来接收消息。这种通信方式会造成一些不必要的浏览器历史记录,而且有些浏览器不支持onhashchange事件,需要轮询才能知道url的变化。最后,这种方式也有缺点,比如数据直接暴露在URL中,数据容量和类型有限等。下面举例说明:如果父页面是baidu.com/a.html,页面iframe中嵌入的是google.com/b.html(此处省略域名等url属性),要实现两个页面之间的通信,可以通过下面的方法。a.html向b.html传输数据,修改a.html下iframe的src为:google.com/b.html#pacob.html检测到url变化,触发相应操作b.html向a传输数据.html,由于两个页面不在同一个域,IE和Chrome不允许修改parent.location.hash的值,所以必须在该域名下的代理iframeb.html下创建一个隐藏的iframe父窗口。这个iframe的src在baidu.com域下,并且挂上要传输的hash数据,比如src="http://www.baidu.com/proxy.ht..."proxy.html监听变化在url中,修改a.htmlurl(因为a.html和proxy.html在同一个域,proxy.html可以修改a.html的urlhash)a.html检测到url变化,触发b.html对应的操作代码:try{parent.location.散列='数据';}catch(e){//ie和chrome的安全机制不能修改parent.location.hash,varifrproxy=document.createElement('iframe');ifrproxy.style.display='无';ifrproxy.src="http://www.baidu.com/proxy.html#data";document.body.appendChild(ifrproxy);}proxy.html页面的关键代码如下://因为parent.parent(即baidu.com/a.html)和baidu.com/proxy.html属于同一个域,所以可以改值它的location.hashparent.parent.location.hash=self.location.hash.substring(1);4。IE8、Chrome、Firefox、Safari、Opera等浏览器通过H5的postMessage()支持这个函数主要包括接收信息的方法和发送消息的postMessage方法。例如damonare.cn域的A页面通过iframe嵌入google.com域的B页面,A和B之间的通信可以通过以下方式实现:A页面通过postMessage发送消息:window.onload=function(){varifr=document.getElementById('ifr');vartargetOrigin="http://www.google.com";ifr.contentWindow.postMessage('你好世界!',targetOrigin);}B页面通过消息事件监听和接受消息:varonmessage=function(event){vardata=event.data;//消息varorigin=event.origin;//消息源地址varsource=event.source;//源窗口对象if(origin=="http://www.baidu.com"){console.log(data);//helloworld!}};if(typeofwindow.addEventListener!='undefined'){window.addEventListener('message',onmessage,false);}elseif(typeofwindow.attachEvent!='undefined'){//foriewindow.attachEvent('onmessage',onmessage);}上面几个方法是在页面和iframe之间或者页面和页面之间。下面是单向跨域,一般用于获取数据。5、script通过JSOP跨域引入的js不受同源策略限制,所以我们可以通过script标签引入一个js或者其他后缀的文件(如php、jsp等),以及该文件返回一个js函数调用。比如有一个页面a.html,里面的代码需要使用ajax获取异域的json数据。假设json数据地址为http://damonare.cn/data.php,那么a.html中的代码可以这样写:因为是作为js文件引入的,http://damonare.cn/data.php必须返回一个可执行的js文件,所以这个页面的php代码可能是这样的,这个需要和后台约定:最后输出结果为:dosomething(['a','b','c']);使用jQuery封装的JSONP方法可以很方便的进行jsonp请求:jquery会自动生成一个全局函数来替换callback=?中的问号,然后获取到数据后自动销毁。其实就是一个临时的代理功能角色。$.getJSON方法会自动判断是否跨域。如果不是跨域,则调用普通的ajax方法;如果是跨域,会以异步加载js文件的形式调用jsonp回调函数。优点:不受同源策略影响,兼容性好,也可以运行在一些古浏览器中,不需要XMLHttpRequest或ActiveX的支持;并且可以在请求完成后调用callback返回结果。缺点:只支持GET请求,无法解决两个不同域的页面之间如何进行JavaScript调用的问题。6、跨域CORS(Cross-OriginResourceSharing)通过CORS实现跨域资源共享,定义了浏览器和服务器在访问跨域资源时应该如何通信。CORS背后的基本思想是使用自定义HTTP标头允许浏览器与服务器通信以确定请求或响应应该成功还是失败。目前所有浏览器都支持该功能,IE浏览器不能低于IE10。因此,实现CORS通信的关键是服务器。只要服务端实现了CORS接口,就可以实现跨域通信。服务器对CORS的支持主要是通过设置Access-Control-Allow-Origin来实现的。如果浏览器检测到相应的设置,就可以允许Ajax跨域访问。CORS与JSONP对比:JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求;使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获取数据,相比JSONP有更好的错误处理。与JSONP相比,CORS无疑更先进、更方便、更可靠。7.window.namewindow对象有一个name属性,它有一个特点:即在一个窗口(window)的生命周期中,该window加载的所有页面共享一个window.name,每个页面都关联到window.name具有读写权限,window.name持久存在于一个窗口加载的所有页面中,不会在加载新页面时重置。例如:我们在任意页面输入window.name="我的窗口名称";setTimeout(function(){window.location.href="http://damonare.cn/";},1000)进入damonare。cn页面然后我们检测再检测window.name:window.name;//Mywindow'sname出于安全原因,浏览器将始终将window.name保留为字符串类型。与document.domain方法相比,该方法放宽了域名后缀必须相同的限制,可以从任意页面获取字符串类型的数据。8.反向代理服务器的基本思路很简单,将你的服务器配置成一个需要跨域获取资源的反向代理服务器。我们只需要配置nginx,在一台服务器上配置多个前缀,就可以将http/https请求转发到多台真实服务器。这样,这台服务器上的所有url都具有相同的域名、协议和端口。所以对于浏览器来说,这些url都是同源的,没有跨域的限制。实际上,这些URL实际上是由物理服务器提供的。这些服务器中的JavaScript可以跨域调用所有这些服务器上的url。