博客系統知多少:揭秘那些不為人知的學問(二)

博客系統知多少:揭秘那些不為人知的學問(二)

大佬說博客

最后更新 2022/3/8 下午9:55
汪宇杰博客
预计阅读 21 分钟
分类
分享
标签
分享

上篇《博客系统知多少:揭秘那些不为人知的学问(一)》介绍了博客的历史、我的博客故事及博客的受众来源。本篇精彩继续,介绍博客基本功能设计要点。

目錄

由於文章篇幅較長,本文將分為 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 講究言語上的規範,連 “讓我們” , “我們來看看” 這種字眼都不能出現。

图 | 网络

文章需要具备标题、Slug、创建时间、发布时间、修改时间、摘要和内容等要素,也会包含所属分类、标签、阅读量和点赞量等次要信息。其中 Slug 是博客的特色,它指的是一篇文章的 URL。例如我的文章:《Try the New Azure .NET SDK》,它的 URL 为 https://edi.wang/post/2019/12/5/try-the-new-azure-net-sdk,其中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 造成災難(我的博客系統因為面向英語用戶,不考慮中文支持,所以並不解決這個問題)。

(图:文章列表中的摘要)

(图:meta description标签代码)

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

(图:必应搜索引擎识别的内容摘要)

文章的狀態通常包括:草稿、發布、回收。用戶僅能看到已發布的文章,管理員可在後台更改文章狀態。

02 評論(comment)

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

我的博客及 wordpress 默認都設計為需要管理員在後台審核評論後,才能放出顯示。這也能有效避免垃圾廣告、騷擾信息甚至是一些惡意的煽動性言論。對於提供 email 地址的用戶,管理員也能夠在後台回復用戶的評論,並由博客系統向用戶發送 email 通知。

(图: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。簡介是對於標題的補充說明,便於用戶查看。設計路由名稱的原因請參考下一段居間的標籤的設計。

(图: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/dotnet-core。

(图: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 年所有的文章。歸檔功能主要用於給讀者按時間查詢,看看博主某個時間都在幹什麼。設計這樣的功能可以提高讀者對博主的興趣,也是個人對外形象的一種展示。

(图:Moonglade博客系统的归档)

06 頁面(page)

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

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

(图:我博客的关于页面)

在我的博客系統中,頁面也選擇是否隱藏側邊欄,用戶也可以完全編寫頁面的 html 及 css 代碼,並把頁面添加為導航菜單。wordpress 對於頁面的處理更加完備,接近於 cms 系統。

07 訂閱(subscription)

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

(图: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 還不行。

(图: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 速度最快,但如果圖片目錄本身位於網站目錄底下,會導致目錄不只讀而引起潛在安全問題。比如早期 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 發送的時候原地爆炸。

下篇將主要居間【博客協議或標準】歡迎關注

汪宇杰

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2022/3/29

疫情下的北京失業中年

最近身邊的一個朋友突然間就被辭退了,而且是一線網際網路大廠,周末跟我聚了下。喝了點小酒,聊了很多,他說我可以把他的經歷發出來,因為他已經看淡了

继续阅读