
博客搭到第10篇說明前面的坑你基本都蹚過來了環(huán)境裝好了、主題調(diào)好了、域名也通了。但我敢打賭你現(xiàn)在多半卡在一個看起來巨簡單、實際上特別容易翻車的環(huán)節(jié)——往文章里插圖片和視頻。要么本地打開好好的一部署上線就變成裂圖要么圖片堆在一起、大小參差不齊要么視頻放進(jìn)去之后頁面直接卡死。這套流程在Hexo里跟你在其他平臺寫博客完全是兩回事因為它是一個靜態(tài)站點沒有“上傳附件”的后臺一切資源都得靠路徑和文件結(jié)構(gòu)自己組織。這篇文章就把圖片、視頻的插入方法、背后的運行邏輯、以及我踩過的各種坑一次說清楚。1. 動手之前先搞明白Hexo里資源文件是怎么流動的1.1 靜態(tài)站的資源處理邏輯Hexo生成站點的方式是把你寫的Markdown文章交給模板引擎渲染成HTML頁面最后把整個public目錄部署到服務(wù)器或托管平臺上。這個流程里最容易被忽略的一點是你的圖片、視頻這些資源文件本質(zhì)上不是什么特殊存在它們就是普通的靜態(tài)文件會被原樣復(fù)制、打包、部署。具體來說你在站點根目錄下通常會看到這樣一層結(jié)構(gòu)source/_posts/存放所有文章的Markdown文件source/images/很多人習(xí)慣把圖片集中放在這里public/執(zhí)行hexo generate之后生成的最終站點文件當(dāng)我第一次搞明白這個機(jī)制的時候?qū)懳恼碌乃悸芬幌戮痛蜷_了。你在Markdown里寫的并不是真的把一個圖片“塞進(jìn)”了HTML里而是告訴瀏覽器去這個路徑下找到pic.png這個文件。所以部署之后你看到的是這樣的情況public/ ├── index.html ├── 2024/ │ └── my-post/ │ └── index.html ├── images/ │ └── pic.png你寫的Markdown和圖片的路徑會在生成時被“拼”到HTML里。圖片能不能顯示完全取決于最終部署環(huán)境里那個路徑下有沒有對應(yīng)文件。理解了這一點你就抓住了Hexo資源管理的命脈你寫的不是文檔是一份帶路徑索引的文件清單。1.2 路徑寫法決定生死相對路徑、根相對路徑與絕對路徑這是新手最容易踩坑的地方而且一旦踩了往往要排查好幾天。Hexo文章里的資源引用本質(zhì)上有三種路徑寫法它們各有各的適用范圍用錯了就會出現(xiàn)“本地正常、線上裂圖”的經(jīng)典問題。第一種是相對路徑比如代表“當(dāng)前文件所在目錄下的pic.png”。這個寫法的坑在于你寫文章的時候覺得沒問題但Hexo生成文章HTML的位置和Markdown文件的位置往往不是同一個目錄。文章Markdown在source/_posts/下生成后的HTML可能在public/2024/xx/index.html路徑一深一淺就全亂了。我自己早期就吃過這個虧在本地hexo server預(yù)覽時一切正常部署上去全是裂圖最后發(fā)現(xiàn)就是相對路徑的說法不成立。第二種是根相對路徑比如以站點根目錄為基準(zhǔn)。這個寫法在大多數(shù)場景下是穩(wěn)的因為source/images/下的東西會原樣復(fù)制到public/images/路徑一一對應(yīng)。但它的前提是你部署在域名根路徑下。如果你部署在某個子目錄里比如https://你的域名/blog/那/images/pic.png會指向https://你的域名/images/pic.png而不是https://你的域名/blog/images/pic.png照樣裂。第三種是絕對路徑比如。這種寫法最直白也不容易出路徑深度問題但缺點是要寫完整域名換域名的時候所有文章里的圖片鏈接都要跟著改非常痛苦。所以我的建議是如果部署在根路徑直接用根相對路徑/images/xxx.png簡單、穩(wěn)定、可遷移如果部署在子目錄要么把站點url和root兩個配置項配好再考慮用相對路徑要么在_config.yml里做一下permalink設(shè)置讓文章生成結(jié)構(gòu)和資源引用結(jié)構(gòu)匹配。關(guān)于這兩種配置項的作用在后面實操部分我會給出一套完整可參考的寫法。2. 圖片插入的三種主流玩法按需選就行2.1 最穩(wěn)的方案source/images集中放置與根相對路徑對于博客剛起步、圖片數(shù)量還不大的階段我強(qiáng)烈建議你先用最“笨”也最穩(wěn)的方法在source目錄下建一個images文件夾所有文章圖片都扔進(jìn)去然后用根相對路徑引用。操作步驟并不復(fù)雜cd 你的博客目錄 mkdir source/images cp ~/Desktop/我的截圖.png source/images/然后在文章里寫你可能會覺得這種方式太土了圖片一多images文件夾里全是文件時間長了根本分不清哪個圖片屬于哪篇文章。這個痛點我太有體會了我的做法是給圖片的文件名加上文章名或者日期前綴比如2024-05-20-hexo-teardown-01.png。這樣就算堆在一個文件夾里至少也能根據(jù)文件名稱快速反查來源。為什么我說這個方案最穩(wěn)因為它不依賴任何插件、不依賴主題的特殊設(shè)置也不依賴生成路徑的深度。hexo generate會把source下的所有內(nèi)容原封不動地拷到public路徑關(guān)系簡單到不可能出錯。把基礎(chǔ)打穩(wěn)再往后面的復(fù)雜方案走心里才有底。2.2 文章自帶圖片post asset folder的正確打開方式如果你希望每篇文章的圖片跟文章正文放在一起形成“文章即文件夾”的強(qiáng)關(guān)聯(lián)結(jié)構(gòu)那就要用到Hexo官方的文章資源文件夾功能也就是post_asset_folder。開啟方式是在站點_config.yml里加一行配置post_asset_folder: true開啟之后每次用hexo new post 文章名創(chuàng)建文章時Hexo會自動在source/_posts/下生成一個與文章同名的文件夾。比如你創(chuàng)建了一篇叫how-to-insert-images的文章就會出現(xiàn)source/_posts/ ├── how-to-insert-images.md └── how-to-insert-images/這個和文章同名的文件夾就是專門給這篇文章存放資源用的。你可以把圖片放進(jìn)去how-to-insert-images/ └── cover.png然后在Markdown里這樣引用這里有一個非常關(guān)鍵的細(xì)節(jié)直接用還是會出現(xiàn)路徑錯亂因為文章最終的HTML生成路徑跟這個文件夾路徑并不一致。所以我需要配合一個路徑修正插件比如hexo-asset-image或者h(yuǎn)exo-image-link。裝了插件之后Hexo在生成HTML時會自動把cover.png修正為/2024/05/20/how-to-insert-images/cover.png這樣的完整路徑這才算真正能用。這個方案的優(yōu)勢非常明顯文章的圖片跟著文章走想看文章時打開同名文件夾對應(yīng)的素材都在里面移植文章到新站點時把.md文件和文件夾一起拷走就行不會丟圖。缺點是必須依賴插件而插件有時候會和特定Hexo版本產(chǎn)生兼容問題。我印象里某個版本的hexo-asset-image對中文路徑的支持就出現(xiàn)過問題后來換成了另一個維護(hù)更活躍的插件才解決。如果你決定走這條路裝完插件一定要先本地預(yù)覽再部署不要直接上線。2.3 封面圖、縮略圖和Markdown/HTML混排的細(xì)節(jié)普通文章中插入圖片已經(jīng)說完了但博客里還有一個高頻需求——封面圖。很多Hexo主題都會在首頁文章卡片上顯示一張縮略圖這個縮略圖的來源通常是文章front-matter里的某個字段最常見的字段名是cover或者thumbnail。寫法大概是這樣--- title: 怎么插入圖片和視頻 date: 2024-05-20 10:00:00 cover: /images/cover.webp tags: [Hexo, 博客] ---這里要特別注意兩點。第一cover的值最好是根相對路徑或完整URL不要用相對路徑因為首頁文章卡片和文章詳情頁所在的URL層級不同相對路徑會直接讓首頁縮略圖裂掉。第二封面圖的尺寸比例很關(guān)鍵不同主題對封面圖的要求不一樣有的偏好16:9有的偏好4:3。裁剪不對的話首頁圖片會被拉伸或裁剪變形很影響觀感。我的習(xí)慣是先在本地用工具把封面圖等比縮放到站點配置中要求的寬高再放進(jìn)source/images/里。還有一個細(xì)節(jié)是Markdown和HTML的混排。Markdown本身不支持下圖片的寬度控制、居中等常見需求遇到這種場景直接用HTML標(biāo)簽反而是最順手的。比如我想讓一張圖居中并且寬度不超過600像素我就會寫div styletext-align: center; img src/images/example.png alt示例圖片 width600 / /divwidth屬性可以直接控制顯示寬度src指向根相對路徑。這套寫法能解決95%的排版需求。如果你想要點擊圖片看大圖的效果那就需要引入支持lightbox的Hexo插件或在主題配置里打開相關(guān)選項不過一般博客剛開始不用搞這么重先讓圖片能正確顯示出來才是第一優(yōu)先級。3. 視頻插入本地視頻、第三方嵌入與HTML5標(biāo)簽的取舍3.1 為什么我不建議直接把視頻塞進(jìn)文章目錄圖片可以放在source目錄下那視頻是不是也可以技術(shù)上可以但實際操作中我強(qiáng)烈不建議原因主要有兩個。第一是體積問題。一段幾分鐘的視頻動輒幾十MB甚至上百MB而Hexo生成的站點最終是要部署到托管空間上的不管是托管平臺的存儲空間還是博客倉庫的體積都會被迅速撐爆。我見過有人把一段1080p的演示視頻直接丟進(jìn)站點目錄結(jié)果每次博客構(gòu)建都要上傳幾百MB的文件構(gòu)建時間長不說訪問速度也極其感人。第二是加載問題。本地視頻文件是“整段存在”的瀏覽器播放它必須等它下載到一定進(jìn)度才能開始用戶打開你的博客時如果網(wǎng)絡(luò)條件一般就會看到視頻區(qū)域空白轉(zhuǎn)圈體驗非常糟糕。而專業(yè)視頻平臺在播放器層面做了大量優(yōu)化有CDN加速、有分片傳輸、有自適應(yīng)碼率播放順暢程度遠(yuǎn)不是自己部署一個MP4文件能比的。所以我的核心建議是除非你是做短小演示片段比如幾秒鐘的動圖式效果否則不要用本地視頻。3.2 第三方平臺嵌入最省心的視頻方案對絕大多數(shù)博客場景最省心的視頻方案是把視頻傳到某個視頻分享平臺然后用它的“分享”功能復(fù)制嵌入代碼粘貼到你的Markdown文章里。以常見的視頻平臺為例你在視頻播放頁找到“分享”按鈕里面通常會有一個“嵌入代碼”或者“復(fù)制HTML”的選項復(fù)制出來的是一段iframe代碼長這樣iframe srchttps://視頻平臺/player/xxxxx width100% height400 frameborder0 allowfullscreentrue/iframe把它直接粘貼到Markdown正文中間的任何位置再保存重新生成頁面里就會有一個完整的視頻播放器。Markdown語法本身是支持內(nèi)嵌HTML的所以不需要任何額外的插件或配置框架類型的東西也不沖突。這段嵌入代碼的好處是視頻文件實際存放在平臺方的服務(wù)器上播放器加載速度、帶寬消耗、移動端適配都由平臺負(fù)責(zé)你只需要提供一個“窗口”。但這里有一條重要的經(jīng)驗嵌入播放器的寬高一定要自己調(diào)好。復(fù)制來默認(rèn)的iframe寬度可能是640px、高度是360px直接放到博客文章里在手機(jī)上看可能直接溢出屏幕。我自己常用的方式是給它加一個寬高比容器div styleposition: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; iframe srchttps://視頻平臺/player/xxxxx styleposition: absolute; top: 0; left: 0; width: 100%; height: 100%; frameborder0 allowfullscreentrue/iframe /div把56.25%換成16:9的寬高比9/160.5625播放器就會自動占滿所在區(qū)域的寬度同時保持16:9的比例在桌面端和手機(jī)端都不會變形或溢出。這個比例容器技巧在任何嵌入視頻、嵌入地圖、嵌入幻燈片時都能復(fù)用非常實用。3.3 HTML5 video標(biāo)簽真正適合自托管視頻的打開方式如果你確實有自托管視頻的需求比如做一個小型演示片段、或者想完全掌控播放器樣式那不要用Markdown語法而是直接用HTML5的video標(biāo)簽。我把一個視頻文件放在source/videos/目錄下之后在文章里這樣寫video controls preloadmetadata width100% poster/images/視頻封面圖.png source src/videos/我的演示.mp4 typevideo/mp4 你的瀏覽器不支持HTML5視頻播放。 /video幾個關(guān)鍵的屬性分別是controls顯示播放、暫停、音量等控制按鈕preloadmetadata只預(yù)加載視頻的元數(shù)據(jù)時長、首幀不預(yù)先加載整個視頻能明顯提升頁面打開速度poster視頻加載前顯示的封面圖沒有它的話頁面上就是一坨黑塊觀感很差typevideo/mp4告訴瀏覽器這是MP4格式我特意用width100%而不是寫死像素寬度為的就是讓視頻在不同屏幕寬度下自適應(yīng)。如果你有多個視頻格式版本比如MP4和WebM可以寫多個source標(biāo)簽瀏覽器會依次嘗試直到找到能播放的格式為止。這種方案的適用場景其實非常窄。我最近一次使用是因為要展示一個很小的錄屏片段壓縮到大約2MB用video標(biāo)簽直接放在文章里效果不錯。如果你手頭的視頻動不動就是幾十MB還是乖乖走第三方平臺嵌入路線吧。4. 完整實操一篇帶圖帶視頻的博文從寫到上線4.1 先初始化資源目錄并調(diào)整主題配置光講理論容易飄我?guī)е阃暾咭槐槲易罱l(fā)的一篇文章的流程這篇文章里包含3張配圖、1張封面圖和1個視頻基本上能覆蓋前面說的所有場景。第一步先檢查站點配置文件。我打開_config.yml確認(rèn)以下幾項url: https://你的域名.com root: / post_asset_folder: trueurl是你的完整域名root是站點根路徑部署在域名根目錄就填/。post_asset_folder如果你決定用文章資源文件夾方案就改成true。但我前面也說了自己圖省事長文章一般還是喜歡把圖片放進(jìn)全局images目錄所以我在實際操作中并沒有長期開啟這個配置項。你根據(jù)自己習(xí)慣選一種即可不要兩個方案混著用——混合用會給自己增加記憶負(fù)擔(dān)時間一長連你自己都記不清圖片到底該放哪。第二步準(zhǔn)備好了目錄mkdir -p source/images mkdir -p source/videos如果你打算用post asset folder則不需要建images目錄把圖片放進(jìn)文章同名文件夾就行。這一步的目的是讓文件有固定的歸處避免隨手下到別的位置。4.2 寫Markdown圖片、封面、視頻的完整代碼塊我這篇文章的front-matter和正文開頭是這樣的--- title: 從零開始搭建博客的十個細(xì)節(jié) date: 2024-05-20 10:00:00 cover: /images/2024-05-20-blog-details-cover.webp tags: [Hexo, 博客搭建] --- ## 1. 第一張配圖的使用示例 這里是一段正常的段落文字。圖片用根相對路徑引用保持簡潔。  這張圖顯示的是Hexo站點的典型目錄結(jié)構(gòu)如果讀者對目錄不熟悉看一眼就懂了。 ## 2. 較大尺寸的圖片用HTML控制布局 下面是寬圖示例超過內(nèi)容區(qū)寬度時會自動撐破排版所以我用HTML包裹并限制寬度 div styletext-align: center; img src/images/2024-05-20-blog-details-02.png alt部署流程圖 width640 / /div ## 3. 視頻嵌入示例 視頻使用第三方平臺的iframe嵌入外層套上了16:9容器的樣式 div styleposition: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; iframe srchttps://視頻平臺/player/視頻ID styleposition: absolute; top: 0; left: 0; width: 100%; height: 100%; frameborder0 allowfullscreentrue/iframe /div這里有幾個操作細(xì)節(jié)我想重點說明。封面圖的文件名我用了-cover后綴配圖用序號01、02這樣source/images里的文件名一看就懂。第二張圖用HTML包裹而不是直接寫Markdown是因為它原始寬度比較大如果不限制寬度在手機(jī)上會被縮放得很小或者撐破布局。第三處是16:9的iframe容器這個在前文已經(jīng)寫了原理這里直接給完整代碼塊你復(fù)制過去就能用。cover字段的值是/images/2024-05-20-blog-details-cover.webp我特意用了WebP格式相比PNG文件體積能小百分之三十以上首頁加載速度會快不少。這個細(xì)節(jié)對圖片多、文章多的站點影響挺明顯的。4.3 本地構(gòu)建、預(yù)覽、部署與線上驗證寫完文章之后我從來不會直接部署上線而是先在本地把構(gòu)建結(jié)果跑一遍。這一步是整套流程中最重要、也最能省時間的環(huán)節(jié)。hexo clean hexo generate hexo serverhexo clean會清除之前的生成緩存hexo generate重新生成靜態(tài)文件hexo server啟動本地預(yù)覽服務(wù)。然后在瀏覽器打開http://localhost:4000找到剛才的文章逐一檢查封面圖是否在博客首頁正常顯示文章里的每張配圖是否都能打開圖片是否有溢出/變形情況視頻iframe是否正常加載頁面的整體排版是否沒受影響我見過太多人跳過本地預(yù)覽直接部署結(jié)果上路之后發(fā)現(xiàn)圖片裂了還要再改再部署反復(fù)折騰效率極低。本地預(yù)覽下發(fā)現(xiàn)的所有路徑問題解決辦法就是回到Markdown里調(diào)整路徑寫法直到本地完全正常為止。確認(rèn)無誤后再執(zhí)行部署命令hexo deploy部署完之后我會從線上站點再走一遍同樣的檢查流程重點確認(rèn)部署環(huán)境里的路徑和本地預(yù)覽是否一致。這一步不能省因為本地環(huán)境有時跟線上環(huán)境在路徑根目錄設(shè)置上存在差異除非你完全用根相對路徑否則線上出問題的概率不小。5. 高頻問題排查圖片不顯示、視頻打不開的常見原因5.1 本地正常線上裂圖八成是路徑基準(zhǔn)選錯了這是被問到最多的問題也是我自己早期踩過最深的坑?,F(xiàn)象非常統(tǒng)一本地預(yù)覽一切正常部署到線上后圖片全掛。問題出在路徑基準(zhǔn)上。本地預(yù)覽服務(wù)處理路徑的時候是以你本地站點的根目錄為基準(zhǔn)的而線上服務(wù)器如果部署在子目錄或者CDN子路徑下根目錄的解析邏輯就變了。你寫的/images/pic.png在本地指向localhost:4000/images/pic.png沒問題到了線上卻指向了域名/images/pic.png而不是你實際部署的域名/博客子目錄/images/pic.png自然就404了。遇到這種情況我的排查步驟是打開瀏覽器的開發(fā)者工具切到網(wǎng)絡(luò)面板找到那張裂掉的圖片請求看它的完整請求URL把請求URL和在線上實際能打開的路徑做對比判斷是路徑基準(zhǔn)問題還是文件缺失問題在網(wǎng)站的public目錄里用文件管理器確認(rèn)圖片是否真的被構(gòu)建到了對應(yīng)路徑如果是路徑基準(zhǔn)問題最簡單的治療方式就是統(tǒng)一改用根相對路徑并保證部署在域名根目錄位置如果你一定要部署在子目錄那就把站點配置文件里的root字段改成對應(yīng)的子目錄路徑比如/blog/讓所有生成出來的資源路徑都帶上這個前綴。改完之后重新構(gòu)建部署裂圖就會消失。5.2 圖片樣式溢出與加載慢的優(yōu)化技巧圖片顯示沒問題但文章頁面看起來很怪——圖片太大、撐破排版、或者整個頁面加載半天。這種問題不屬于路徑而是樣式與性能層面的。樣式問題最常見的場景是直接在Markdown里插了一張?zhí)貏e寬的全景圖。Markdown默認(rèn)會按原始尺寸渲染圖片如果不限制寬度圖片寬度超過文章內(nèi)容區(qū)域頁面就會出現(xiàn)橫向滾動或布局?jǐn)D壓。解決方案就是我在前面反復(fù)提到的改用HTML標(biāo)簽加上width屬性或放在容器里控制寬度。加載慢的問題則是性能和體積問題。一張未經(jīng)壓縮的照片可能有3MB博客首頁若有10篇文章展示縮略圖那就是30MB的加載量不慢才怪。我的優(yōu)化清單是圖片先壓縮再上線推薦把單張圖片控制在200KB以內(nèi)能用WebP就不用PNG或JPEG同等畫質(zhì)下體積小很多封面圖、縮略圖這類重復(fù)出現(xiàn)的圖片盡量用統(tǒng)一的尺寸裁剪讓瀏覽器利用緩存如果圖片數(shù)量真的大考慮引入云存儲加內(nèi)容分發(fā)網(wǎng)絡(luò)加速這里就不展開細(xì)說了我最近在調(diào)整圖片性能的時候把首頁的縮略圖全部替換成了WebP格式同樣的視覺觀感下整個首頁的圖片加載體積從將近10MB降到了2MB左右打開速度提升非常明顯。這個收益幾乎是零成本的強(qiáng)烈建議你也試一下。5.3 視頻不播放、白屏、卡頓的排查順序視頻相關(guān)的問題相對少一些但一旦出問題也是最讓人頭疼的。常見的問題和排查順序我?guī)湍阏砹艘幌氯绻堑谌角度氲膇frame白屏先直接打開那個iframe的src地址看看視頻平臺本身是否能正常播放。如果平臺頁面能放但你的博客頁面里是白屏極大概率是平臺禁止了網(wǎng)站的iframe嵌入或者需要你配置域名白名單。有些平臺也會限制某些開發(fā)者密鑰的使用范圍。如果是自托管視頻不播放先檢查瀏覽器開發(fā)者工具里視頻請求的返回狀態(tài)。常見的情況是404路徑錯了或者跨域錯誤視頻文件域和博客頁面域不同且沒有正確的響應(yīng)頭。路徑錯了就去調(diào)整source標(biāo)簽的src屬性跨域錯則需要你在靜態(tài)托管平臺配置跨域響應(yīng)頭難度稍高但前提條件是你的托管平臺支持這個自定義配置。如果視頻卡頓、加載慢那就不是代碼問題了而是文件存放位置的帶寬瓶頸。第三方平臺的視頻卡頓大概率是用戶網(wǎng)絡(luò)和視頻平臺節(jié)點之間的鏈路問題沒什么好辦法自托管視頻卡頓就一句話把視頻從本地挪到對象存儲平臺或者干脆換用第三方嵌入方案。我的排查順序始終是先復(fù)制播放地址直接在瀏覽器打開再檢查瀏覽器網(wǎng)絡(luò)請求狀態(tài)最后才回頭審視代碼。這個順序能幫你快速區(qū)分“資源本身有問題”和“自己代碼有問題”避免白費功夫亂改。說到最后分享一個我現(xiàn)在的默認(rèn)做法配圖全部走source/images加根相對路徑封面用統(tǒng)一尺寸的WebP格式視頻一律用第三方平臺iframe嵌入。這套組合已經(jīng)穩(wěn)定跑了大半年幾乎沒有再為資源問題頭疼過。你如果剛開始折騰不用把方案都想全了再動手先把一套最簡單的跑通后面再根據(jù)文章數(shù)量的增長逐步優(yōu)化這才是Hexo最常見的正確打開方式。