本文实例讲述了JS防止网页被嵌入iframe框架的方法。
防止网页被Frame,方法有很多种;
方法一:常见的比如使用js,判断顶层窗口跳转:
js 代码:
<script type="text/javascript"> if (window!=top) // 判断当前的window对象是否是top对象 top.location.href = window.location.href; // 如果不是,将top对象的网址自动导向被嵌入网页的网址 </script>
这段代码是有效的。但是,有一个问题:使用后,任何人都无法再把你的网页嵌入框架了,包括你自己在内。
于是,我今天就在考虑,有没有一种方法,使得我的网页只能被嵌入我自己的框架,而不是别人的框架?
表面上看,这个问题很简单。只要做一个判断:当前框架和顶层框架的域名是否相同,如果答案是否,就做了一个URL重定向。
if (top.location.hostname != window.location.hostname) { top.location.href = window.location.href; }
但是,出乎意料的是,这样写是错误的,根本无法运行。你能看出,错在哪里吗?
假定 top.location.hostname 是 www.111.com,而 window.location.hostname 是 www.222.com。也就是说,111.com把222.com嵌入了它的网页中。这时,比较 top.location.hostname != window.location.hostname 会有什么结果?
浏览器会提示代码出错!
因为它们跨域(cross-domain)了,浏览器的安全政策不允许222.com的网页操作111.com的网页,反之亦然。IE把这种错误叫做"没有权限"。进一步说,浏览器甚至不允许你查看top.location.hostname,跨域情况下,一看到这个对象,就直接报错。
那么,代码应该如何修改?
事实上,这提示我们,只要查看top.location.hostname是否报错就可以了。如果报错了,表明存在跨域,就对top对象进行URL重导向;如果不报错,表明不存在跨域(或者未使用框架),就不采取操作。
try{ top.location.hostname; }catch(e){ top.location.href = window.location.href; }
这样写已经正确了,在IE和Firefox中可以正确运行。但是,Chrome浏览器会出现错误,不知为何,在跨域情况下,Chrome对top.location.hostname不报错!
没办法,只能为了Chrome,再加一段补充代码。
try{ top.location.hostname; if (top.location.hostname != window.location.hostname) { top.location.href =window.location.href; } }catch(e){ top.location.href = window.location.href; }
好了,升级版代码完成。除了本地域名以外,其他域名一律无法将你的网页嵌入框架。
一般这样够用了,但是有一次发现失效了,看了一下人家网站就是顶层窗口中的代码,发现这段代码:
js 代码:
var location = document.location; // 或者 var location = "";
轻轻松松被破解了,悲剧。
注:此方式破解对IE6,IE7,IE9+、Chrome、firefox无效
方法二:meta 标签:基本没什么效果,所以也放弃了:
html 代码:
<meta http-equiv="Windows-Target" contect="_top">
方法三:使用HTTP 响应头信息中的 X-Frame-Options属性
使用 X-Frame-Options 有三个可选的值:
DENY:浏览器拒绝当前页面加载任何Frame页面
SAMEORIGIN:frame页面的地址只能为同源域名下的页面
ALLOW-FROM:origin为允许frame加载的页面地址
绝大部分浏览器支持:
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 4.1.249.1042 | 3.6.9 (1.9.2.9) | 8.0 | 10.5 | 4.0 |
具体的设置方法:
Apache配置:
html 代码:
Header always append X-Frame-Options SAMEORIGIN
nginx配置:
html 代码:
add_header X-Frame-Options SAMEORIGIN;
IIS配置:
html 代码:
<system.webServer> ... <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> </customHeaders> </httpProtocol> ... </system.webServer>
web.config 设置 X-Frame-Options 的方法,不少文章都有介绍过,代码看似简单,但一不小心就会出现错误,例如代码块放错了地方。这里我提供一个完整的web.config代码,可以更清楚的看到代码块的位置。
代码如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <connectionStrings> <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> <authentication mode="Forms"> <forms loginUrl="~/Account/Login.aspx" timeout="2880" /> </authentication> </system.web> <system.webServer> <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> </customHeaders> </httpProtocol> </system.webServer> </configuration>
说明, <httpProtocol>...</httpProtocol> 整块代码一定要放到 <system.webServer>...</system.webServer> 里面,尤其要注意的是, <system.webServer>...</system.webServer> 与 <system.web>...</system.web> 是并列的代码块,相互不能被包含。
X-Frame-Options 有三个值:
DENY
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM uri
表示该页面可以在指定来源的 frame 中展示。uri 是网页地址,如:http://www.webkaka.com/
web.config 设置 X-Frame-Options 无效的原因
做项目时,有可能遇到 web.config 设置 X-Frame-Options 无效的情况,请确认自己已经重启了IIS。如果不行,试试下面的代码:
<system.webServer> <httpProtocol> <customHeaders> <add name="Content-Security-Policy" value="default-src: https:; frame-ancestors 'self' X-Frame-Options: SAMEORIGIN" /> </customHeaders> </httpProtocol> </system.webServer>
代码解释,您的 web.config 条目需要在 Content-Security-Policy (内容安全策略)下才能使用之前没有折旧的编码。 value ="default-src: https:"内容安全策略下的值对您的网站是唯一的。
重要的内容是 'value =“default-src: https:' 后面的内容,但最重要的是包含在内容安全策略中。
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛