因為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運作的過程,發現:
$.ajax()
的方式取得內容,然後用$.html(內容)
的方式來顯示$.html()
的內容,把script tag內的Javascript程式,用eval()
來執行$.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)