因为Mozilla最近推出了一个网站安全设定检测的服务:OBSERVATORY,所以就用它来检测一下,并且尝试根据他的建议调整伺服器设定(在测试机上)。
这些设定其实大部分只要设定标头就可以做到,Contnet Security Policy就是其中一个,只要设定好Content-Security-Policy标头,支援的浏览器就会依照这个指定的政策来做来源的控管。例如:
Content-Security-Policy: default-src 'self' 'unsafe-inline' cdnjs.cloudflare.com
这样指定以后,除了来自网站本身的资源、还可以使用cdnjs来的js档以及在html元素中使用javascript来处理事件或是用style属性指定样式。例如:
...<link type="text/css" rel="stylesheet" href="/style/main.css" /><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>...<!-- 设定'unsafe-inline',下面这行才会动 --><a href="#" onclick="alert('oh no');return false" style="display:inline-block;height:48px;width:48px">Don't Click</div><!-- 设定'unsafe-inline',才允许在script tag中写javascript --><script>$(function() { $('#btn').click(function(e) {e.preventDefault(); console.log('btn clicked')};});</script>
因为拿掉'unsafe-inline'规则的话,势必要大改...所以就加上去,心想我应该没有在Javascript中使用eval()才对,不知道多少年没这样用了...所以没有加上'unsafe-eval',心想应该没问题。
测试一下发现...用来当做MessageBox的fancybox全挂了
关键:如果用fancybox载入的内容,含有script tag就一律挂:
<script>$('#msg').click(function() {...});</script>
甚至
<script src="/js/popup.js"></script>
都一样。
追了一下fancybox跟jQuery运作的过程,发现:
如果不设定使用iframe,fancybox会用$.ajax()
的方式取得内容,然后用$.html(内容)
的方式来显示jQuery会剖析传给$.html()
的内容,把script tag内的Javascript程式,用eval()
来执行jQuery会剖析传给$.html()
的内容,把script tag指定的来源档案用$.ajax()
的方式抓下来,然后用eval()
来执行就是这样...因为要透过$.html()
动态显示的内容中有script tag,所以jQuery用eval()
帮你执行了......回想当初没用iframe,是因为fancybox不一定抓得到iframe内容的宽与高来自动调整,为了偷懒所以没使用的啊XD(改用iframe的话,只好让这些popup在载入完成后,document.body.scrollWidth及document.body.scrollHeight确定了,再呼叫外层的函数来调整大小及位置)
总之,$.html()
不仅仅是innerHTML的包装,他还多做了许多事情,会在你不知道的地方使用eval()
喔。(其实在使用innerHTML的时候,页面是会reflow,但是Script并不会被执行的哪。也因为这样,所以jQuery帮你做了XD)