两年前,我写过一段代码,防止网页被嵌入框架(Frame)。
<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;
}
好了,升级版代码完成。除了本地域名以外,其他域名一律无法将你的网页嵌入框架。我的Blog现在就使用这段代码。
==============================
P.S.
除了代码以后,我还有一件事要说。
今年6月5日,在《创业途径:手工杂志》一文的最后,我说:
"喜欢手工的女同学们,建议你们试试。只要你的作品有趣,我帮你在我的Blog上推广。"
结果,真的有女同学找我。Daisy来信说,她和女友做了一本电子杂志《上班族》,希望我帮忙推广。

虽然我对上班这件事一点兴趣也没有,也不觉得这种主题值得做,但是我不想食言,而且我一向觉得,追求梦想的人值得鼓励。所以,欢迎大家阅读。
最后,为了增加点击率,Daisy同学自愿提供了一张生活照。

(完)



colin 说:
杂志做的不错,值得鼓励。
有梦想就有可能!
2010年8月15日 21:40 | 档案 | 引用
ddd 说:
我不能理解不能嵌入别人的框架对你有什么好处?
2010年8月15日 21:48 | 档案 | 引用
ok 说:
这个都不能理解?省流量,省麻烦啊
2010年8月15日 22:38 | 档案 | 引用
Alvan 说:
window.onbeforeunload = function() {
return "请问是否关闭本页面";
}
iframe页面加入该代码后,如果被嵌入页面执行跳转,浏览器就会跳出对话框询问用户是否要关闭页面——如果用户点“否”,那么你的这些努力就都白费了。
防止网页被嵌入框架的代码叫frame killer,上面的这段代码就叫做frame-killer killer
2010年8月15日 22:54 | 档案 | 引用
sophiasmth 说:
你这个想要破解也是很简单的,只能应付一些初级的程序员,无用功
2010年8月15日 23:38 | 档案 | 引用
LuciferByron 说:
电子杂志业不是已经全军覆没了吗
2010年8月16日 11:07 | 档案 | 引用
Daisy 说:
难道是北邮的Daisy学姐!?
2010年8月16日 11:58 | 档案 | 引用
hipboi 说:
本来还想看看,结果放了照片。。。就不想看了 :)
2010年8月16日 13:34 | 档案 | 引用
OceanBan 说:
2010年8月17日 08:49 | 档案 | 引用
Daisy 说:
没关系,我经得起打击。其实准确地说,也不能算是我主动提供照片,是您说为了提高点击量,可能有照片更好。我本来就是对这些小事情都很无所谓的人。无论如何,谢谢一峰帮忙宣传。非常感谢。
我的电子杂志没准有一天也会死掉,但至少我试过了。至少目前身在职场看过的人,很多人还是觉得有可看之处的。
也希望大家用宽容和好奇的心态来看看罗。
2010年8月19日 00:01 | 档案 | 引用
auchan 说:
看看!很不错哦!!
2010年8月19日 14:39 | 档案 | 引用
小扁豆 说:
加油~Daisy :)
2010年8月19日 16:54 | 档案 | 引用
依云 说:
我觉得那个用来看杂志的Flash用户体验非常不好,翻页和阅读都很不方便,也没找到能用的目录。
2010年8月19日 18:30 | 档案 | 引用
yurii 说:
阮兄你好,最近在读《软件随想录》,部分文字我有不同看法,特来与您商榷,比如《大构想的陷阱》(94页)开头:
眼睛的工作方式同页错误(page-fault)机制有类似之处。它运作起来如此完美,以致于你都不会察觉到它是怎么运作的。
译本给“页错误”加了注释:页错误指的是应用程序读取物理内存的某段地址时,其中没有包含数据,导致出错。
我读这句话非常迷惑,结合下文想了很久才明白这里的“页错误”是什么意思:据我估计,此处的page-fault指的是操作系统采用的虚拟页式内存管理机制(而且应用程序并不能直接读取物理内存某段地址,只能通过操作系统读取逻辑地址),用户以为数据都在物理内存中,其实数据是由操作系统根据需要从硬盘调换到内存中的。这样理解,下文说眼睛其实也只能保持对一个小区域的清晰成像,而人却以为自己能清楚看到“整个视野”,就顺理成章了。
所以我建议翻译为:
眼睛的工作方式类似电脑的虚拟页式内存管理机制(注释:虚拟页式内存管理机制是指操作系统并不会把所有数据都保存在物理内存中,而是保存在外存中,程序需要时再调入内存,用户感觉不到这个过程,以为数据是全都在内存中的)。它运作起来异常完美,你都察觉不到真正的细节。
2010年8月20日 14:14 | 档案 | 引用
Ruan YiFeng 说:
其实,我不懂什么叫“页错误”,当时看了网上的解释,也没搞明白。我也觉得应该就是指硬盘虚拟内存,但是不确定,只好按照字面译。如果能够确定,那你的翻译就是对的。
2010年8月21日 06:29 | 档案 | 引用
larz 说:
这段文字的问题看似只有一个点,实则影响了译者翻译全书的方式,也就是译者假定本书的读者层级 - 科班?非科班?
想来Joel这段文字假定读者具有基本的OS概念(大多为科班),因此也就不作解释。而一峰兄非科班出身,这些译注想来是写给非科班的读者看,可惜背景所限,译注的内容反有误导之嫌
要解释页错误,无法靠译注的一两句话就能达成。它是虚拟内存管理机制中重要的一环,不可能只解释一个点,就让读者能理解整个面,结果读者最后还是一知半解。
我觉得与其强迫自己去解释不熟悉的东西,还不如保留原文术语而不多作处理,科班读者一眼即知在说什么(他们更熟悉原文术语,也更有突出性),而非科班的读者可以此查询wiki获得更完整的解释
--
页错误是一个系统信号用来管理虚拟内存。当应用程序读取虚拟内存(物理内存+分页档)的某个页面(某段地址),若此页面不在物理内存中,就产生一个页错误,告诉OS要去分页档取出需求的页面,置入实体内存中。所有流程都由OS在背景处理,用户无须关心。
2010年8月30日 13:56 | 档案 | 引用
Jake 说:
Dr. Ruan,
Greetings! I am sorry for bothering you a bit.
May I know if you have any knowledge if Google will penalize the sites that apply this of your anti-framing code. When checking out on some English tech blogs, they just speculate Google may down-rank the concerned websites but offer no proof that the search engine giant will sure to do so.
Looking forward to your answer and many thanks in advance!
All the best
Yours faithfully,
2010年11月26日 02:32 | 档案 | 引用
lj 说:
《上班族》挂了?就看了个封面
2011年2月18日 14:15 | 档案 | 引用
笨小孩 说:
很好,谢谢,但这种情况下不适用,123.abc.com中框架456.abc.com中的一个页面,也会出错,但是都是自己的二级域名,有什么好办法吗?
2011年3月12日 06:58 | 档案 | 引用
Ruan YiFeng 说:
那只有比较top.location.hostname 和 window.location.hostname的主域名了。
2011年3月12日 22:31 | 档案 | 引用