部落格系統知多少:揭祕那些不為人知的學問(二)

微軟技術棧發表於2021-10-08

上篇《部落格系統知多少:揭祕那些不為人知的學問(一)》介紹了部落格的歷史、我的部落格故事及部落格的受眾來源。本篇精彩繼續,介紹部落格基本功能設計要點。
由於文章篇幅較長,本文將分為4篇推送,目錄如下:

  1. “部落格”的前世今生
  2. 我的部落格故事
  3. 誰是部落格的受眾?
  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. 部落格協議或標準

    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. 設計部落格系統有哪些知識點

    6.1 時區真的全用UTC?

    6.2 HTML還是Markdown

    6.3 MVC還是SPA

    6.4 安全

  7. 結束語

01 文章(Post)

我們每天可能都會閱讀或長或短的3-5篇文章。文章是部落格系統的核心業務,因此部落格文章的內容和質量非常重要。

那麼,文章這個業務型別如何起名?資料庫的表名和程式碼的變數名,型別名稱用article嗎?好像上學時候只學過文章叫做article。其實部落格型別的文章,正確的表達是post,英文單詞裡post和article的區別在於,post只是隨心所欲寫的文章,而article指的是論文那樣的經過精心雕琢,旁徵博引,並且有可能在學術期刊上發表的文章。因此設計部落格系統的時候,儘量避免使用article這個單詞來命名程式碼。更具體來講,post中可以出現不嚴謹、口語化的表達方式,例如本文就算是個post。而article講究言語上的規範,連 “讓我們” , “我們來看看” 這種字眼都不能出現。
11.gif

圖 | 網路

文章需要具備標題、Slug、建立時間、釋出時間、修改時間、摘要和內容等要素,也會包含所屬分類、標籤、閱讀量和點贊量等次要資訊。其中Slug是部落格的特色,它指的是一篇文章的URL。例如我的文章:《Try the New Azure .NET SDK》,它的URL為 https://edi.wang/post/2019/12...,其中try-the-new-azure-net-sdk即為該文章的Slug。Slug講究的是“人類可讀”,一般情況下均為部落格標題對應的英文表達,用中劃線分割英文單詞,Slug也對部落格的SEO起到了關鍵作用。如果你的部落格文章用的是資料庫ID、文章標題的HTML Encoding等做URL,請更換為Slug。特別是遇到中文文章,如果標題被URL Encoding了,那麼對於SEO和連結分享,都是災難。一個Slug一旦定下,儘量不要改動,雖然大部分部落格系統都支援修改Slug,但是對於被搜尋引擎收入的文章,改了Slug就會導致404。比較完備的部落格系統(如WordPress)支援採用301重定向方式告訴搜尋引擎原文地址已變化。

摘要有兩個作用,一是用於在列表檢視中顯示文章資訊預覽,二是用於SEO,放在description這個meta標籤中,可以幫助搜尋引擎精準定收入的內容。對於中文內容,需要注意是否輸出的HTML原始碼被Encoding過,ASP.NET Core預設的Encoding會對SEO造成災難(我的部落格系統因為面向英語使用者,不考慮中文支援,所以並不解決這個問題)。

image.png
(圖:文章列表中的摘要)

image.png
(圖:meta description標籤程式碼)

摘要可以自動抓取文章前幾百字,也可以像微信公眾號那樣要求使用者手工填寫。我的部落格採用的是自動取文章前400字。結合SEO的關係,我的文章通常開頭段落就是概要,這樣可以讓使用者在搜尋引擎預覽頁面就能看到準確內容,而不是頁面上無關緊要的UI元素。

image.png
(圖:必應搜尋引擎識別的內容摘要)

文章的狀態通常包括:草稿、釋出、回收。使用者僅能看到已釋出的文章,管理員可在後臺更改文章狀態。

02 評論(Comment)

評論是部落格中作者和讀者互動的主要方式。有些部落格要求讀者登入後才能發表評論,而有些可以允許遊客評論(比如我的部落格及WordPress)。登入的好處在於可以識別你的讀者,並有效防止垃廣告評論。但要求登入也會給使用者造成操作上多了一個步驟,嫌麻煩的使用者就不會進行評論。

我的部落格及WordPress預設都設計為需要管理員在後臺稽核評論後,才能放出顯示。這也能有效避免垃圾廣告、騷擾資訊甚至是一些惡意的煽動性言論。對於提供Email地址的使用者,管理員也能夠在後臺回覆使用者的評論,並由部落格系統向使用者傳送Email通知。
image.png

(圖:Moonglade的評論區)

對於技術部落格,評論可考慮開放markdown格式。這是一種在程式設計師之間格外受歡迎的語法,在GitHub得到了廣泛應用。

評論需要採用驗證碼或其他人機驗證技術,以防止機器人發廣告。但根據經驗,驗證碼並不能100%阻止垃圾資訊,因為現代化的垃圾資訊還真的是人組團發的,有專門的公司、團隊、微信群等,國外也有。於是,你可能需要考慮關鍵詞過濾,購買三方過濾介面等。

評論也得記得做字數限制,不然也有可能會造成部分使用者“灌水”、刷屏的現象。

如果不想自己寫功能,還可以整合三方的評論服務,即部落格系統本身不實現評論功能,通過三方服務載入外部JS,在文章閱讀頁面“注入”一個評論區,通常這要求文章的URL不變(WordPress裡叫做永久性URL)。

03 分類(Category)

像建資料夾一樣將文章根據內容進行區分,即為分類。文章分類後,可以幫助讀者快速檢索同種類的文章。

例如寫.NET、PHP、JS的文章都屬於 “開發技術(Development)”這個分類。而技術圈新聞和職場經驗分享和等文章,則屬於 “工作” 分類,分類的劃分完全由使用者控制。分類可以多對多。例如寫一篇文章介紹了用ASP.NET Core開發Angular應用的文章,可以同時屬於 “.NET技術” 及 “前端開發” 分類。

分類需要一個標題、一個簡介,以及一個路由名稱。例如我部落格,微軟雲 Azure 的分類,標題為 Microsoft Azure,簡介為 The Best Cloud,路由名稱為azure。標題需要同時顯示在標題欄,以便於SEO。簡介是對於標題的補充說明,便於使用者檢視。設計路由名稱的原因請參考下一段介紹的標籤的設計。
image.png

(圖:Moonglade部落格系統的一個文章分類)

分類的另一個功能就是產生 OPML 及 RSS/Atom 訂閱源,這個將在第五章介紹部落格協議中講解。

04 標籤(Tag)

一篇文章所提到的話題,即為文章的標籤。和分類一樣,標籤也是多對多關係。標籤可以作為檢索文章的依據,類似關鍵詞,快速查詢相關內容的文章。

標籤需要考慮到標籤含義重複的情況,例如:VS和Visual Studio是一個意思,VSCode、VSC和Visual Studio Code也是一個意思。那麼使用者選擇標籤的時候,最好使用智慧提示推薦使用者使用已有標籤。

對於部落格系統設計者來說,還要考慮標籤的URL。如果URL用的是標籤本身的內容,會導致很多問題。當標籤名稱為整個英文單詞,例如Excel,並不會發生問題,因為URL通常是https://yourblog/tags/excel。但是如果標籤內容為 .NET Core、C#、Robots.txt,事情就變的有意思起來。https://yourblog/tags/robots.txt到底是在請求 tags下的robots.txt 檔案還是在請求標籤?自己作為部落格系統設計者,當然可以從程式上限制所有tags接受的路由引數都為標籤,好像是解決了問題,但SEO和掃描工具可不這麼認為,他們有大量by convention的規則會認為是請求檔案。

對於需要URL Encoding的標籤內容,更會導致URL缺乏可讀性,從而影響SEO。千萬不要自作聰明地以為現代的搜尋引擎可以處理好URL Encoding,一個URL是否乾淨對SEO的影響很大。特別是當標籤是中文內容的時候,如果全encoding了,URL就會非常冗長,甚至影響到SEO,也影響到博主分享連結。因此,我的部落格系統為了處理標籤URL,給每個標籤都設計了規範化名稱(normalized name),由系統根據標籤內容自動產生,如 .NET Core 經過 normalize,會變成 dotnet-core,最終產生的URL即 https://edi.wang/tags/list/do...
image.png

(圖:Moonglade部落格系統的標籤)

對於使用者來說,最容易犯錯之一的就是把標籤用成搜尋關鍵詞。例如使用者寫了一篇關於 Visual Studio Code的文章,那麼標籤可能會同時打VSCode、VSC和Visual Studio Code,但其實只要選擇一個標籤即可。打太多同樣含義的標籤會導致讀者無法完整檢索到所有相關文章,對搜尋引擎來說,也是如此。所以如何用好標籤,是部落格設計者和使用者需要共同關注的要點

標籤雲(Tag Cloud)是部落格中用來列出最熱門標籤的功能。通常使用跟大號字、更明顯的顏色來標識出對應文章較多的標籤。標籤雲可以作為部落格博主的個性化屬性,一眼就能看出博主熱衷於什麼話題(比如Windows Phone?0.0)。

05 歸檔(Archive)

以時間(年、月、日)整理的部落格文章即為歸檔,它和分類的區別在於歸檔只以時間為標準來劃分文章。Archive的SEO相對於文章、分類、標籤來說,並不那麼關鍵。所以除了URL可以按年月劃分以外,並沒有額外的講究。

例如:https://edi.wang/archive/2019/9 表示2019年9月的文章。https://edi.wang/archive/2019 則表示2019年所有的文章。歸檔功能主要用於給讀者按時間查詢,看看博主某個時間都在幹什麼。設計這樣的功能可以提高讀者對博主的興趣,也是個人對外形象的一種展示。
image.png

(圖:Moonglade部落格系統的歸檔)

06 頁面(Page)

頁面是部落格的可選功能之一,事實上,它更接近於CMS的功能。有些內容並不適合以文章的形式釋出,比如“關於”頁面。這樣的頁面通常與釋出時候的時間無關,內容也經常更新,排版設計也非常自由,不單純是文字。

頁面通常不需要評論、標籤和分類等屬性,但可以有釋出和編輯時間。和文章一樣,頁面也需要注意Slug。

image.png
(圖:我部落格的關於頁面)

在我的部落格系統中,頁面也選擇是否隱藏側邊欄,使用者也可以完全編寫頁面的HTML及CSS程式碼,並把頁面新增為導航選單。WordPress對於頁面的處理更加完備,接近於CMS系統。

07 訂閱(Subscription)

讀者訂閱部落格的主要方式有Feed(RSS/ATOM)及Newsletter。Feed方式本質上是被動訂閱,需要客戶端軟體發起請求給伺服器,檢查是否有新文章發表,才能顯示到客戶端裡。Newsletter一般採用Email形式主動傳送給訂閱使用者,但這要求部落格系統的編寫者實現Email訂閱功能,也要求管理員維護Email服務。訂閱一般只推送近期發表的新文章,例如前10、20篇,而不會每次都推送全部文章導致客戶端爆炸。

image.png
(圖:Moonglade的RSS/ATOM訂閱源)
訂閱一般可按文章分類提供,以便於只對某些分類感興趣的讀者閱讀。有些部落格系統也提供文章評論的訂閱源,以便讀者觀摩吐槽大會。

關於RSS及ATOM的詳細介紹請看5.1、5.2章節。

08 版本控制

更接近CMS的部落格系統通常提供版本控制功能,允許使用者回滾文章或頁面的歷史版本。設計版本控制的時候,不能只考慮往前回滾,得還能再滾得回來。通常,使用者每次編輯一篇已經寫好的文章,就會產生一個新版本,類似於git對於一個檔案的commit。部落格的版本控制也類似於程式碼版本控制,你可以選擇儲存一篇文章的完整內容作為歷史版本,也可以選擇每次只儲存變化量資訊(delta)。儲存完整內容不容易後續花費大量時間精力 ,但是會佔用較多儲存空間。儲存內容變化量節省資料庫空間,但實現程式碼容易佔用大量精力。

09 主題及個性化

好用的部落格系統通常支援主題,畢竟個性化是部落格本身應有的特點之一。WordPress積累了大量的主題庫,也允許自制主題。但是我的部落格只支援更改主題色,還有很大上升空間。

10 使用者及許可權

部落格系統分為個人、團隊及部落格平臺。個人部落格系統一般為單使用者(例如我的部落格),不需要設計許可權、註冊等功能。多使用者部落格則需要實現不同的角色和許可權,比如部落格管理員、稽核專員、撰稿人、評論管理員等等。無論是單使用者還是多使用者部落格,整合一套成熟的三方RBAC方案可能是最高效的選擇,多數三方方案也都支援SSO,例如我部落格支援的Azure AD。

11 外掛

外掛功能可以在不更改部落格程式碼的情況下,按需擴充部落格的功能。WordPress以及BlogEngine都支援外掛,但Moonglade還不行。
image.png

(圖:WordPress的外掛市場)

12 圖片及附件的處理

圖片格式

在2020年,圖片格式已經非常自由,一般的部落格JPG居多,程式設計師的部落格PNG居多(畢竟都是螢幕截圖),像微信公眾號那樣採用WEBP格式現在同樣可取,只要讀者的裝置相容即可。一般BMP格式由於體積大會導致網路傳輸慢,所以不推薦。同樣道理,GIF也要注意限制尺寸。

部落格系統輸出圖片時,需要採用正確的Mime Type,以保證客戶端的相容性。一般直接輸出靜態檔案本身不需要部落格編寫者手工處理Mime Type,但有專門圖片處理邏輯的部落格(例如我的Moonglade)則需要留意保留圖片原本的Mime Type。

圖片水印

給上傳的圖片自動加水印有助於保護版權,水印內容一般是部落格的地址或博主名字。新增水印時要注意圖片尺寸調整水印的比例,以免擋住圖中重要內容影響閱讀。對於過小的圖片,可選擇性的忽略水印。

另外,考慮到部落格有可能會在發展過程中改名,建議新增水印的時候在系統中保留一份原始圖片,以便於後期更新水印內容。

具體方法可參考我的文章《ASP.NET Core 給上傳的圖片加水印》。

圖片儲存

圖片存哪裡是個值得思考的問題。一般有3個地方存放:檔案系統、資料庫、雲上的Blob儲存服務。Moonglade支援檔案系統及Azure Blob儲存。這三者各有優缺點。

檔案系統的優勢在於直接serve static file速度最快,但如果圖片目錄本身位於網站目錄底下,會導致目錄不只讀而引起潛在安全問題。比如初中時候很流行的給DVBBS上傳個改了擴充名的ASP web shell,儘管給web伺服器上傳可執行檔案在2020年已經基本絕跡了,但依然存在隱患,就好比就算你家裡請了007當保鏢也是需要夜間鎖好門。

資料庫存圖安全性最高,並且讓部落格的資料只位於一個位置,方便管理和備份,十幾年前很流行這麼做,但其實讀寫圖片對資料庫有一定開銷,並且再由網站輸出,雙倍開銷,一般不推薦。

而云端Blob儲存服務目前來說是最適合這個時代的方案,將圖片儲存在Blob中不僅能保證伺服器目錄只讀,又能採用雲本身的安全特性限制非正常訪問,還能通過CDN加速圖片輸出。要硬說缺點,就是雲服務需要額外的金錢,而沒錢,是自己的問題,不是雲的問題。

圖 | 網路

圖片防盜鏈

作為網站開發者,我們有時候不希望自己網站的圖片被其他網站直接引用。這在某些場景下會導致自己資料中心裡巨大的頻寬消耗,也就意味著別人使用我們的圖片,我們要為此付錢。例如,你的網站是a.com,你有一張圖片是http://a.com/facepalm.jpg,而b.com在他們的網站上使用一個img標籤來引用了你的圖片,這導致網路請求是進入你的資料中心,消耗你的資源。因此部落格可選擇性的啟用防盜鏈功能,具體方法可參考我的文章《ASP.NET / Core 網站圖片防盜鏈》。

附件

通常程式設計師的技術部落格會提供讀者下載程式碼樣例等附件。設計附件功能和設計圖片儲存非常類似,完全可行。但我更建議技術部落格將程式碼示例等附件託管到其他網站(例如GitHub)提供讀者下載。

自己部落格實現附件下載的壞處有:

大檔案

不同的Web伺服器及防火牆產品對檔案尺寸的限制不同,而部署部落格的使用者很可能無權管理這些限制,就會導致大附件無法提供下載。

域及IP黑名單

某些公司或組織(特別是安全規範較高的軟體公司)會遮蔽非白名單域的檔案下載,儘管你可以用瀏覽器正常開啟該域的網頁,但無法下載檔案(防火牆只允許HTML/CSS/JS等,而不允許ZIP、EXE等)。而程式設計師部落格的讀者很有可能就處在這樣的公司裡。

CDN資源耗費

如果你的附件較多,較大,並且你也像設計圖片儲存一樣給附件系統套了個CDN,此時根據CDN服務商計費模式的不同,如果按流量計費,恐怕你的附件下載會導致你的錢包加速瘦身。

而採用三方檔案下載(如GitHub、OneDrive)的好處有:

√ 你的檔案不僅可以分享到部落格文章中,也可以分享到別的位置;

√ 這些三方服務有自己的CDN,而不用擔心消耗你自己的錢包;

√ 許多檔案託管服務有完整的管理功能,例如檔案刪除、恢復、版本控制、許可權等,要是自己在部落格系統裡寫一個這個,需要花費大量時間……

13 敏感詞過濾及評論審查

部落格難免引來一些抱有敵意的人,也會引來發廣告的人,所以通常需要敏感詞過濾和評論審查。如果沒有審查直接將使用者的評論顯示在文章下,那麼可能會對博主和網站本身帶來不良影響。例如,有人發了政治敏感的言論或者不合規的廣告,沒有經過後臺稽核就直接顯示出來了,而你的部落格部署在大陸,那麼你的部落格很可能會被馬上關停整頓,並且自己也會解鎖程式設計師從入門到如入獄的成就。也千萬不要以為部署在境外就沒事了,一些仇恨性質的言論甚至可以幫你引來黑客,在你的部落格裡下毒,勒索你或你的讀者。

因此我強烈建議個人部落格啟用敏感詞過濾及評論審查功能。WordPress及我的Moonglade部落格系統均支援敏感詞過濾和評論審查。

14 靜態化

早期的新聞系統、部落格、CMS為了提高大訪問量下的響應速度,都會採用靜態化技術,即將服務端渲染完的頁面儲存為真正的HTML檔案於磁碟上,進行static file的輸出,Web伺服器輸出static file的效率非常高,對於不變的內容,使用者的後續訪問不會hit資料庫,因此極大減小了伺服器的壓力。在2020年的今天,靜態化已經不是唯一的方案,Redis Cache也可以幫助我們減少對資料庫的頻繁訪問。對於個人部落格來說,如果你的訪問量不高,其實並不需要996一個靜態化或Redis出來增加開發和維護成本。但如果你設計的是部落格平臺,那麼最好還是用上靜態化或Redis吧。

15 通知系統

部落格通常通過Email的形式給管理員或使用者傳送通知。但是沒有規範或或約定表示部落格是否一定得使用Email進行通知推送,可由部落格系統設計者自行決定。

通知通常包括:

向博主傳送的通知:新評論、文章被他人部落格引用(參見第5.8, 5.9章)。

向使用者傳送通知:新文章釋出(訂閱Newsletter)、評論被回覆、評論稽核通過或被拒。

Email通知系統要注意垃圾郵件及使用者隱私保護問題。

垃圾郵件發給博主本身問題並不大,但得注意郵件系統是否會允許未經博主許可的針對讀者的郵件傳送,其中可能會被人利用發垃圾郵件,從而導致伺服器被封禁。有些伺服器供應商,例如微軟Azure,對於郵件有更加嚴格的規定,部署在部分PaaS業務上的程式碼呼叫SMTP終端會被直接遮蔽。

對於使用者隱私問題,在使用者向部落格系統提供Email地址的同時,需要告知使用者該Email地址會被如何使用(可寫在隱私協議或頁面可見區域),也可以讓使用者勾選是否允許博主使用該Email進行通知推送。另一個問題是郵件地址暴露,這通常發生在Newsletter的訂閱群發,如果把所有訂戶的Email地址都放在To或CC裡,那麼每個使用者都會知道其餘所有人的Email地址,從而互相約炮、欺詐,因此Newsletter請採用BCC或單獨傳送,並允許使用者退訂。

Moonglade的通知系統採用Email方式,但設計比較基礎。一個完善的通知系統需要採用訊息佇列及事件設計,並採用三方服務。例如Azure上可以使用Storage Queue + Function App + SendGrid,以免遇到大批量Email傳送的時候原地爆炸。

明天將主要介紹【部落格協議或標準】歡迎關注!


掃碼關注微軟MSDN,獲取更多微軟一手技術資訊和官方學習資料!
image.png

相關文章