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

跨域,了解

时间:2023-04-05 13:35:44 HTML5

跨域理解跨域,顾名思义,就是向不同的域请求资源。要理解跨域这件事,我们先来看看跨域问题的根源:浏览器的同源策略,浏览器的同源策略是什么鬼?好像有点明白了,又不是很清楚。这一次我们将详细探讨它。声明一下,本文是在参考了很多其他跨域文章结合自己的技术知识做的记录。请参考浏览器的同源策略及其规避方法,比较合适。同源策略:(same-originpolicy)MDN维基百科:在计算中,同源策略是web应用安全模型中的一个重要概念。根据该政策,网络浏览器允许第一个网页中包含的脚本访问第二个网页中的数据,但前提是两个网页具有相同的来源。源被定义为URI方案、主机名和端口号的组合。此策略可防止一个页面上的恶意脚本通过该页面的文档对象模型获取对另一个网页上敏感数据的访问权限。简单翻译:在Web应用安全模型中,同源策略是一个重要的概念。在这种策略下,Web浏览器允许包含在第一个页面中的脚本访问来自第二个网页的数据,前提是两个页面具有相同的源。源被定义为URI协议、主机名、端口号的组合。此策略可防止一个页面上的恶意脚本通过文档对象模型(DOM)获取其他网页的敏感数据。那为什么会有同源策略呢?你可以参考这篇关于CSRF的文章。哪些数据会受到限制?敏感数据一般是指浏览器中的Cookies、SessionStorage、LocalStorage、IndexedDB数据、CacheStorage、ApplicationCache……;阮一峰先生也总结了同源策略对非同源的限制行为:“如果不是同源,限制的行为有3种。(1)无法读取Cookies、LocalStorage、IndexDB。(2)获取不到DOM。(3)无法发送AJAX请求。虽然这些限制是必须的,但有时很不方便,也影响合理使用。下面,我将详细介绍如何规避以上三种限制。”下面对阮老师总结的方法进行测试。Cookie浏览器允许通过设置document.domain共享cookie。需要对document.domain进行写操作。只能写基础域名和当前域名,不能写其他域名,所以domain方法只能在父子域名之间共享cookie//由于没有相关资源(三级域名resources,域名资源),没有验证iframe第1页localhost:8080的页面是否包含第2页(iframe=http://localhost:8081);访问页面2中的window.parent.document报跨域错误,可以访问页面2中的window.parent,但是访问iframe得到的window.parent对象中的属性缺少DOM相关的部分。在第1页直接查看window对象时,可以看到document属性对象,但是使用window.parent是获取不到document属性对象的。片段标识符(fragmentidentifier)window.name跨文档消息传递API(Cross-documentmessaging)片段标识符fragmentidentifier那么这样一来,无论是否有源,父窗口都可以改变hash值在子窗口iframe的src,用于向子窗口传递数据;但是在跨域的情况下,子窗口获取parent.location.href(可写但不可读),读取操作会报跨域错误,所以子窗口课件写入url传递数据到父窗口。片段标识符方法可以从父亲传给儿子,也可以从儿子传给父亲。window.namedocument.getElementById('iframe').contentWindow.name访问错误,所以不能跨域window.postMessagepage1调用iframe的iframe.contentWindow.postMessage(data,"http://localhost:8081")page2调用window的window.parent.postMessage(data,'http://localhost:8080')AJAX(最常见的情况)》同源策略规定AJAX请求只能发送到同源URL,否则报错会报Except绕过这个限制的方法有3种,通过设置服务器代理(浏览器请求同源服务器,后者请求外部服务)JSONPWebSocketCORS”JSONP//客户端(浏览器页面)函数addScriptTag(src){varscript=document.createElement('script');script.setAttribute("type","text/javascript");script.src=src;document.body.appendChild(script);}window.onload=function(){addScriptTag('http://example.com/ip?callback=foo');//需要指定回调函数名}functionfoo(data){console.log('你的公网IP地址是:'+data.ip);};//serverfoo({"ip":"8.8.8.8"});CORSCORS是Cross-OriginResourceSharing的缩写。它是W3C标准和跨源AJAX请求的基本解决方案。与只能发送GET请求的JSONP相比,CORS允许任何类型的请求。请参考阮老师的跨域资源共享CORS详解