上篇《博客系统知多少:揭秘那些不为人知的学问(三)》介绍了博客协议或标准。本篇终章介绍设计博客系统有哪些知识点。
目錄
由於文章篇幅較長,本文將分為 4 篇推送,目錄如下:
- “博客”的前世今生
- 我的博客故事
- 誰是博客的受眾?
- 博客基本功能設計要點
- 4.1文章(post)
- 4.2評論(comment)
- 4.3分類(category)
- 4.4標籤(tag)
- 4.5歸檔(archive)
- 4.6頁面(page)
- 4.7訂閱
- 4.8版本控制
- 4.9主題及個性化
- 4.10用戶及權限
- 4.11插件
- 4.12圖片及附件的處理
- 4.13髒詞過濾及評論審查
- 4.14靜態化
- 4.15通知系統
- 博客協議或標準
- 5.1 RSS
- 5.2 ATOM
- 5.3 OPML
- 5.4 APML
- 5.5 FOAF
- 5.6 BlogML
- 5.7 Open Search
- 5.8 Pingback
- 5.9 Trackback
- 5.10 MetaWeblog
- 5.11 RSD
- 5.12閱讀器視圖
- 設計博客系統有哪些知識點
- 6.1時區真的全用 utc?
- 6.2 html 還是 markdown
- 6.3 mvc 還是 spa
- 6.4安全
- 結束語
6.1 |時區真的全用 utc?
存儲時間使用 utc 在 2020 年應該已經是猿盡皆知的實踐了,博客系統其實也是如此,我的博客所有時間數據最終保存都採用 utc 時間。但博客有個特殊的地方,即它不應該按讀者的時區去轉換 utc 時間進行顯示,而應該按照博客作者的時區去顯示時間。
這並不是技術上的原因,就算你按讀者時區去顯示時間也不會有代碼爆炸,原因在於博客的誕生初衷,就是為了彰顯個性,讓博主在網際網路上有自己的展示空間,因此突出博主本人的屬性非常重要,博主所在時區也是個讓讀者了解博主的屬性之一,因此,正宗的博客系統都會給一個時區設置選項,並以此轉換 utc 時間作為顯示,wordpress 和我的 moonglade 博客系統均是如此。博客系統不自動轉換讀者所在時區的時間,純粹就是個鮮為人知的情懷設計,但必須得尊重。

那麼有意思的事情來了,搜尋引擎要怎麼理解博客文章的時間?最好將 utc 時間僅告訴搜尋引擎,不要給用戶顯示,方法也很簡單,用 html5 的 time 標籤的 datetime 屬性即可。在 html5 標準推廣以後,搜尋引擎更喜歡看標籤類型來判斷內容的含義,而不是根據標籤里的內容來猜意思。
在 c#里,tostring(“u”)指的是 universal sortable date/time patter。
<time datetime="@Model.PostModel.PubDateUtc.ToString("u")" title="GMT @Model.PostModel.PubDateUtc">@DateTimeResolver.GetDateTimeWithUserTZone(Model.PostModel.PubDateUtc).ToString("MM/dd/yyyy")</time>
對於剛才截圖裡的文章,時間的 html 為:
<time datetime="2020-04-29 11:41:02Z" title="GMT 4/29/2020 11:41:02 AM"
>04/29/2020</time
>
6.2丨 html 還是 markdown
許多技術人士編寫博客系統的時候喜歡選用 markdown 作為編輯器,如果單純只是個技術博客,自己使用並沒有什麼問題。但如果你在給他人編寫博客系統,請記住,不是每個人,都是程式設計師,不是每個人,都喜歡 markdown。

在這種情況下,一個 wsiwyg 的 html 編輯器(如 tinymce)是不錯的選擇,html 編輯器相對 markdown 也支持更高級的排版方式。moonglade 同時支持 html 和 markdown 編輯器。

保存文章内容到数据库时,Markdown 格式需要选择原始内容,而非生成的 HTML,因为还需要支持后续编辑。HTML 格式现在也不建议 encoding 存储,毕竟都已经 2020 年了,市面上的主流数据库都可以正确支持各种神奇的 Unicode,比如文章中突然出现个 emoji😂,而如果你使用了 encoding,就会像我的博客一样面临一些福报:https://github.com/EdiWang/Moonglade/issues/280。并且 encoding 和 decoding 的过程会影响性能。我的 Moonglade 博客系统也刚刚完成了去除 encoding 的改造。
6.3丨 mvc 還是 spa
許多社區里寫博客系統的程式設計師都偏向於使用 spa 架構建博客,而鄙視用 mvc,覺得落後,真的是這樣嗎?這個問題就像是飛機為什麼不飛直線,是航空公司不會規劃嗎?關於這一點,我曾經在以前的博客文章《我的 .net core 博客性能優化經驗總結》中寫過:
2014 年以後,隨著 spa 的興起,angular 等框架逐漸成為了前端開發的主流。它們解決的問題正是提升前端的響應度,讓 web 應用儘量接近本地原生應用的體驗。我也面臨過不少朋友的質疑:為什麼你的博客不用 angular 寫?是你不擅長嗎?

其實並不是那麼簡單。實際上我任職的崗位目前主要工作內容也是寫 angular,博客曾經的.net framework 版的後台也用過 angularjs 以及 angular2,經過一系列的實踐表明,我博客這樣的內容站用 angular 收益並不大。
其實這並不奇怪,在盲目選擇框架之前,我們得注意一個前提條件:spa 框架所針對的,其實是 web 應用。而應用的意思是重交互,即像 azure portal 或 outlook 郵箱那樣,目的是把網頁當應用程來開發,這時候 spa 不僅能提升用戶體驗,也能降低開發成本,何樂而不為?但是博客屬於內容為主的網站,不是應用,要說應用也勉強只能說博客的後台管理可以是應用。博客前台唯一的交互就是評論、搜索,因此 spa 並不適合這樣的工作。這就像你要去菜場買菜,騎自行車反而比你開個坦克過去方便。
在微軟官方文檔里也有同樣的關於何時選擇 spa,何時選擇傳統網站的參考:
博客前台仍然選用 mvc 的另一個原因,請回顧一下本文開頭“博客的讀者是誰”,我運營博客十餘年,統計的數據表明,幾乎所有的用戶都來源於搜尋引擎,都只點進來看一篇文章,然後關閉網頁。現在仔細想想,spa 解決的最大的問題之一是什麼?是不是通過只刷新局部來提高前端性能(可響應度)?而用戶從搜尋引擎過來,只看一篇文章就關閉網頁,真的用得到 spa 只刷新局部的優勢嗎?用戶只看一篇文章,你用個 spa 框架,用戶得加載一堆框架本身的文件,其中包括導航、交互等功能,而 99%的用戶根本就不會點到別的地方去,於是你只為了 1%的用戶,去加載碩大的一個框架,值得嗎?這性能到底是提高了,還是降低了?
mvc 框架雖然每次都會輸出伺服器端渲染的完整 html,但由於 99%的用戶只看一篇文章就關閉網頁,所以對於 99%的用戶來說,他們所需要加載的資源,遠小於加載一套 spa,速度更快,還更 seo 友好。spa 適合用在博客的後台管理 portal,而不是前台。
6.4丨安全
根據運營博客多年的後台監控數據,最常見的攻擊行為是全自動的漏洞掃描工具。他們會請求例如data.zip, wp-admin.php, git 目錄等常見的安全疏忽,或是想要通過某些博客系統的已知漏洞進行攻擊。目的是為了控制伺服器,在你的博客網頁里加入對用戶的惡意代碼(例如勒索病毒、挖礦)等,有些也會將伺服器本身變成礦機。

设计博客系统时,常用的安全对策可参考 OWASP(https://owasp.org/),但同时保留灵活性。例如,加入 JavaScript 的 CSP 时,请考虑正常博客用户可能需要添加三方统计插件(如 Azure Application Insights,国内的 CNZZ 等),请设计一定的黑、白名单或功能开关。
大部分設計者都知道要防範用戶的輸入,即博客的讀者,輸入的入口通常只有評論和搜索功能。但不要忘了,博主在博客後台管理中的輸入也需要防範,因為不一定是博主本人在操作。舉個例子,博主的帳號被盜,黑客在後台將導航欄的連結指向黑客的伺服器或 localhost 上早已準備好的奇妙的機關(是的,不要以為 localhost 在正常人的電腦上不起作用),那麼讀者就會受到嚴重影響。

關於後台登錄的身份認證,能採用成熟的 sso 的就優先採用 sso,例如 moonglade 支持 azure active directory 驗證,這樣能夠利用微軟這樣的專業服務管理授權認證,儘可能小的避免帳戶上產生安全問題。如果用戶沒有 sso 的環境,才 fallback 到本地帳號認證。千萬不要認為用三方服務沒自己寫安全,覺得自己寫的邏輯沒人知道就不會被黑了,除非你是世界頂級大牛,不然自己寫的系統易黑程度遠高於三方服務。
另有一些攻擊通常由一些敵對陣營的無聊程式設計師發起,例如使用腳本或工具持續不斷的請求博客系統的某個 url,企圖像 ddos 那樣擊爆伺服器,對於這種無聊刷刷黨,博客系統設計者只要加入有關 url endpoint 的 rate limit 即可。對於真實的 ddos 攻擊,只有雲端抗 ddos 服務或硬體 ddos 防火牆才能解決。
最后别忘了 OWASP 里没有的东西,博客的协议也会有设计缺陷,例如 pingback 可以用来 DDOS(https://www.imperva.com/blog/wordpress-security-alert-pingback-ddos/),也能扫描服务器端口(https://www.avsecurity.in/wordpress-xml-rpc-pingback-vulnerability/)
結束語
設計一個優秀的博客系統,每一處細節都值得斟酌。這些設計絕對不可能一開始就能做對,而是得靠長期運營博客的數據去發現並思考。並且,市場會變化,用戶行為會變化,標準會被淘汰,也會被發明,因此你的系統需要跟著進化。
任何看似簡單的系統,就算普通到爛大街,也有背後看不見的一套完整體系。博客如此,電子商城、外賣、金融清算系統更是複雜,不要光憑自己表面看到的就開始做。就如同造飛機,造個紙飛機和真飛機,絕對不是一回事。
技術人員也不要覺得什麼流行就得用什麼,優秀的產品並不是堆砌時髦技術做出來的,而先得分析你的用戶到底是怎麼用你的產品,才能做最合適的選擇。要記住,想要一件事情做成功,思路不要只局限於技術本身,學會分析市場,用戶行為,才能更準確的選擇和應用技術。

感謝讀到這裡的讀者,如果大家有什麼疑問和討論,歡迎留言交流。
下篇將主要居間【設計博客系統有哪些知識點】歡迎關注
