镇江市建设局网站,c网站开发视频,时装网站的建设,企业网站怎么建设公司本文所有案例在本地址都可找到#xff1a;https://github.com/dancingZhou/sameOrigin/tree/dev
什么是同源策略
两个页面地址中的协议、域名和端口号一致#xff0c;则表示同源。
例如该地址 https://www.google.com 和以下地址对比
地址同源原因http://www.google.com否…本文所有案例在本地址都可找到https://github.com/dancingZhou/sameOrigin/tree/dev
什么是同源策略
两个页面地址中的协议、域名和端口号一致则表示同源。
例如该地址 https://www.google.com 和以下地址对比
地址同源原因http://www.google.com否协议不一致https://google.com否域名不一致https://www.google.com:81否端口号不一致https://www.google.com/a/s.html是协议域名和端口号都一致
同源策略的限制 存储在浏览器中的数据如localStroage、Cooke和IndexedDB不能通过脚本跨域访问 不能通过脚本操作不同域下的DOM 不能通过ajax请求不同域的数据
为什么要同源策略
设置同源限制主要是为了安全如果没有同源限制存在浏览器中的Cookie等其他数据可以任意读取不同域下DOM任意操作Ajax任意请求的话如果浏览了恶意网站那么就会泄漏这些隐私数据。
Cookie一般用来保存登录状态。在登录一个银行网站后此时浏览器中就保存了登录的状态同时浏览了恶意网站这时Cookie的信息没有同源限制的话恶意网站就可以获取这些Cookie信息来达到不为人知的目的。
如果可以操作不同域下的DOM可以用如下方式完成盗取信息。在自己的网站上嵌入一个iframe地址设置成银行地址然后让iframe全屏显示当你一不小心上当了输入你账号密码我就可以通过DOM操作获取到输入的信息。
Ajax的限制同Cookie如果带上Cookie去跨域访问接口就可以通过程序的验证被认为身份是合法的。
既然瞥见危害一角自然要严加防范限制非同源操作。
怎么规避同源策略
在看法一个网站的过程中有的数据并不在同一台服务器上这时怎么跨域调用就是一个很棘手的问题可以通过以下几个方式来规避同源的限制。
DOM同源策略的规避
hash
因为hash的改变并不会引起页面的刷新同时可以通过 window.onhashchange事件监听到hash的改变所以可以通过hash来跨域传递数据。
!-- http://example.com/index.html --
htmlheadmeta charsetutf8/title跨域DEMO --- hash/title/headbodyiframe idiframe srchttp://example2.com/index.html/iframescriptvar ifra document.getElementById(iframe);ifra.onload function(){// ifra 加载完成了ifra.src ifra.src #data;}/script/body
/html!-- http://example2.com/index.html --
!-- 在iframe中的页面example2.com如果和iframe所在页面(example.com)不同域是不能获取所在页面的DOM然后通过hash将数据传递回去的也就是说如果同域就可以通过该方法向所在页面传递数据 --
htmlheadmeta charsetutf8/title跨域DEMO --- hash/title/headbodyscriptwindow.onhashchange function(){// 打印通过hash传过来的数据console.log( location.hash ); }/script/body
/html该方法会直接暴露所传递的数据并且对所传数据有大小限制。
document.domain
若两个文档的域相同则可以获取对方的DOM对象并且可以通过设置 document.domain 的值来让两个文档的域保持一致但是 document.domain 并不是可以设置任何值只能设置为当前域的超域比如
m.example.com 设置为 example.com并且不能 example.com 设置为 m.example.com 也不能将 m.example.com 设置为 example2.com。
所以document.domain只可以在拥有相同的主域名的不同子域名之间跨域。
!--http://a.example.com--
htmlheadmeta charsetutf8/title跨域DEMO --- document.domain/title/headbodyp iddata我在 a.example.com 下/piframe idifra srchttp://b.example.com/index.html/iframescript// 这里为什么也要设置呢因为document.domain的赋值会导致端口被覆盖成null并且js中没有手段单独设置端口所以这里设置一遍这样就和iframe中的一致了。document.domain example.com;var ifra document.getElementById(ifra);ifra.onload function(){console.log( ifra.contentWindow.document.getElementById(data).innerHTML ); // 我是b.example.com下的}/script/body
/html!--http://b.example.com--
htmlheadmeta charsetutf8/title跨域DEMO --- document.domain/title/headbodyp iddata我是b.example.com下的/pscriptdocument.domain example.com;console.log( parent.document.getElementById(data).innerHTML ); // 我在 a.example.com 下/script/body
/htmlwindow.name
window.name有一个特性即使当前窗口的地址改变了window.name的值也不会改变。可以利用这一特性来进行跨域步骤如下
通过iframe加载需要获取数据的地址在加载的文件上将数据设置到window.name上数据获取完成后将iframe的地址设置为当前文档同域通过DOM操作拿到window.name上的数据
!--http://example.com--
htmlheadmeta charsetutf8/title跨域DEMO --- window.name/title/headbodyiframe idifra srchttp://example2.com/index.html/iframescriptvar retData false;var ifra document.getElementById(ifra);ifra.onload function(){if( !retData ){ifra.src http://example.com/index.htmlretData true;}else{console.log( ifra.contentWindow.name ); // 我在example2.com下}}/script/body
/html!--http://example2.com--
htmlheadmeta charsetutf8/title跨域DEMO --- window.name/title/headbodyscriptwindow.name 我在example2.com下;/script/body
/htmlwindow.postMessage
以上几种跨域的方法都属于破解行为而postMessage是H5为跨域提供的解决方法。
otherWindow.postMessage(message, targetOrigin[, transfer])!--http://example.com--
htmlheadmeta charsetutf8/title跨域DEMO --- window.postMessage/title/headbodyiframe idifra srchttp://example3.com/index.html/scriptvar ifra document.getElementById(ifra);ifra.onload function(){ifra.contentWindow.postMessage(我来自example.com, http://example3.com)}/script/body
/html!--http://example3.com--
htmlheadmeta charsetutf8/title跨域DEMO --- window.postMessage/title/headbodyiframe srchttp://example2.com/index.html/scriptwindow.addEventListener(message, function(messageEvent){console.log( messageEvent.data ); // 我来自example.com}, false)/script/body
/htmlmessageEvent对象上的属性中有三个属性要注意分别是
source 发送消息的窗体origin 发送消息的域名 (根据域名判断是否处理该消息)data 发送消息的内容 (获取发送的消息内容)
Ajax同源策略的规避
jsonp
虽然跨域限制了Ajax请求但是却并不影响跨域引用脚本。
scriptfunction callback (data) {console.log(data); // 上面的加载完成之后就会打印出后台传过来的数据 数据}
/script
script srchttp://example.com/index.php?argval1jsonpcallback/script
?phpecho $_GET[jsonp] . ( . 数据 . );
?上面的 index.php 接口返回的是一段调用 函数的js代码 callback(data)其中data就是接口要返回的数据。而这个callback是事先在页面上写好的处理数据的回调函数并且回调函数的名称通过URL参数的形式传递给了后端接口这样就完成了一次跨域。
注jsonp只支持GET请求。
CORS
cors(跨域资源共享)
参考
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policyhttps://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessagehttp://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html