做過小試驗,主要用於美化界面、增強頁面內容交互性,無關安全性討論,一切全靠自覺. ...
Conmajia
January 20, 2019
警告 這是試驗,警告個屁,請不要多多嘗試用它做多餘的事。
果不其然,這篇文章立刻被移出主頁了,我就說嘛,這博客園哪兒會那麼包容和坦然呢?
原文
document.title = "[我是 JS 生成的!] " + document.title
標題其實是有點問題的,會讓人覺得我在搞破壞,找漏洞。NONONO,這是誤會,我最多就是想拿 JS 改改預設的主題什麼的。實際上,這種擔心是不存在的。 BKY 本身並沒有屏蔽 JS 腳本,甚至在後臺主動開放了 HTML 許可權,以一個 BK 網站來說,比較良心了。加上現在改成 Markdown 編輯器,還支持文章正文內插入 HTML,整個 BK 的可玩性更高了。
畢竟它壓根兒就沒有擴展功能的插件和可編輯的主題,再不開放許可權還玩您 呢?
只是總有人不小心搞出一些事來,為了網站安全,不得不屏蔽掉文章里的 <script>
標簽。
所以現在你如果在文章里寫上 JS,它沒法運行。如果做試驗,你寫:
前面的正文
<script type="text/javascript">
document.title = Math.random()
</script>
後面的正文
然後把文章發表出來,你會發現這段壓根兒就不顯示、不執行,煙兒似的就消失了,屁反應沒有。
那怎麼辦啊,就沒招改改預設主題了嗎?好些人說,
預設主題也挺好的啊,還有那麼多五顏六色的可以選呢。
您是認真的嗎?啊?預設的那些主題實在是太難看了啊,難道這就是傳說中的程式員的審美觀麽?9021 年了,醒醒,大清已經亡了!村裡通網多少年了,Web 都已經 4.0,5.0,6.0 了,老鐵!
如果某天你意識到了這一點,精通增刪改查的你也許會想要給自己的 BK 整個容?加點料?刪點自帶的垃圾?在讀者打開你每篇文章時都跳出點不同的東西?
你知道我在說什麼,畢竟你那麼聰明。
都已經開放 HTML 了,你當然可以用各種姿勢咯美化界面咯,我這個 BK 就有很多東西是代碼生成的。還有一個好處是增強了文章的互動性,提高讀者參與度。比如你要講隨機數,編了無數代碼,作者寫得天花亂墜,讀者看得暈頭轉向:
Math.random()
吧啦吧啦逼逼半天,能有我一個按鈕的效果好?
或者用較小的篇幅展示更多內容?比如點下麵的按鈕:
如何評價程式員的審美?走進地鐵的一瞬間,大家就感受到了前所未有的尷尬,有人說這是程式員下班了……
$(document).ready(function(){
$("#flip").click(function(){
$("#panel").slideToggle("slow");
});
});
所以現在我來說說怎麼運行文章正文里的 JS 代碼。你知道的,JS 有一個 eval
函數專門 evaluate 字元串形式的代碼。那麼,look at 管理→設置
自定義 HTML 的地方:
非常幸運,eval
函數可以執行,這就簡單至極了。既然正文里的 <script>
屏蔽了,改從外圍執行代碼就好啦。舉個例子,在正文里用一個標簽 <run>
包住要執行的代碼,直接 eval
:
<!-- 頁面底部 HTML 設置 -->
<script>
$(function(){
$('run').each(function(){eval($(this).text())});
});
</script>
這樣,頁面載入完後,就會依次執行正文里所有 <run>
標簽內的代碼了。美觀一點,可以把所有 <run>
都隱藏起來:
/* CSS 設置 */
run {
display: none;
}
一開始那個例子改改,文章里寫上:
前面的正文
<run>
document.title = Math.random()
</run>
後面的正文
發表文章就能看到效果了(↑↑ 你再看看本文的標題欄?):
這不就繞過屏蔽了?但是吧,我給的例子里只簡單地使用了 eval
,它有時候是不靈光的。因為 Markdown 編輯器會把代碼里的 $
、*
、_
這些特殊符號識別成格式開關,然後把代碼渲染得面目全非,根本沒法用。所以你需要想辦法阻止編輯器解析你的代碼!來看個稍微複雜點的例子:
<run>
$('html').attr('lang', 'zh-CN');
$('title').text(Math.random() * 100 * 99);
</run>
只有兩句話的代碼,被 Markdown 編輯器解析成了一大堆 HTML 標簽:
<run><br>
<span class="MathJax_Preview" style="color: inherit; display: none;"></span>
<span class="MathJax" id="MathJax-Element-2-Frame" tabindex="0" style="position: relative;" data-mathml="
<math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mo stretchy="false">(</mo>
<mo>&#x2032;</mo></msup><mi>h</mi><mi>t</mi><mi>m</mi><msup><mi>l</mi><mo>&#x2032;</mo>
</msup><mo stretchy="false">)</mo><mo>.</mo><mi>a</mi><mi>t</mi><mi>t</mi><mi>r</mi><msup>
<mo stretchy="false">(</mo><mo>&#x2032;</mo></msup><mi>l</mi><mi>a</mi><mi>n</mi><msup>
<mi>g</mi><mo>&#x2032;</mo></msup><msup><mo>,</mo><mo>&#x2032;</mo></msup><mi>z</mi>
<mi>h</mi><mo>&#x2212;</mo><mi>C</mi><msup><mi>N</mi><mo>&#x2032;</mo></msup>
<mo stretchy="false">)</mo><mo>;</mo></math>" role="presentation">
<!-- (省略幾十行) -->
<script type="math/tex" id="MathJax-Element-2">('html').attr('lang', 'zh-CN');
</script>('title').text(Math.random() * 100 * 99);<br>
</run>
大部分是 MathJax 的數學公式解析,因為它用 $
作為行間公式的識別符,而 jQuery 好死不死幾乎全是 $
……至於解決方案,你可以在選項
里禁用數學公式,
或者換一個不支持 Markdown 的編輯器,
或者你可以想點別的招。有一種臨時的解決方案是把代碼放在 <run>
的某個屬性里,eval
改成從屬性中讀取,比如:
<run code="$('html').attr('lang', 'zh-CN');$('title').text(Math.random() * 100 * 99);"></run>
</code>
$('run').each(function(){eval($(this).attr('code'))});
需要說明的是,這篇文章寫的東西並不是找出 BKY 的 bug,最多算留出了非常大的自由度。至於怎麼使用,還是得看個人素質了。
我說明個幾把。
我強烈懷疑有些重要的語句是無法執行的,不過我沒有試過,我也不知道事實如何。
The End. \(\Box\)