☰
Hexo博客图片视频插入全攻略:路径、图床、嵌入与性能优化
2026/10/13 12:01:06 网站建设 项目流程

很多人在Hexo博客搭建的时候,最容易被卡住的不一定是主题配置,而是"图片到底怎么放进去,视频到底怎么嵌进来"。之前我把文章写好了、部署上线了,结果点开一看,图片全是一个个裂开的小图标,视频区域直接空白。那感觉就是精心装修好的房子,结果窗户全碎了。这篇我打算把一直在用的图片和视频插入方法彻底理一遍,从最简单的本地路径到外链图床,再到视频的几种嵌入方式,一次说透,照着抄基本不会再踩坑。

1. 先搞清楚图片裂掉的根本原因:路径、仓库和渲染的关系

Hexo本身不是一个"所见即所得"的编辑器,你写的Markdown文件只是源文件,真正显示在网页上的是它经过渲染之后生成的静态HTML。所以图片能不能显示,不在于它的本地路径对不对,而在于图片有没有被正确地放到最终生成的public目录里,以及文章里的引用路径能不能和部署后的URL对得上。

最常见的裂图场景有三个。第一个是直接在文章里写了类似![](./xxx.png)这样的相对路径,但图片文件其实还在source目录下的原位置,根本没有被复制到public目录,部署后自然找不到。第二个是用了类似/images/xxx.png的绝对路径,但图片并没有放在source/images下面,路径名对不上。第三个是图片放在了文章的专属文件夹里,但没有开启Hexo的post_asset_folder,资源没有被按文章结构拷贝。

理解这个问题,可以先看Hexo的构建流程。你在博客根目录执行hexo generate时,Hexo会把source目录下的所有内容,经过一个渲染过程,输出到public目录。Markdown文章被渲染成HTML,但文章里引用的图片本身不是"自动跟随"的。也就是说,图片文件必须满足两个条件:一是它得在source目录体系内,二是文章里指向它的路径必须能对应到部署后的URL结构。

以默认配置为例,如果图片放在source/images/abc.png,你在文章里写![](/images/abc.png),部署到GitHub Pages或自己的服务器时,浏览器会访问你的域名/images/abc.png,这个文件确实存在于public目录下,所以可以正常显示。但如果你把图片随手放到了语言文件夹或者主题目录里,情况就会变得复杂,路径很容易错位。

还有一个容易被忽略的问题:如果你设置了permalink: :year/:month/:day/:title.html这样的文章链接结构,那么文章本身的URL是带层级目录的。此时如果用相对路径去引用同级图片,就要考虑页面URL和图片URL之间的相对关系,层级一旦变多,相对路径就很容易写错。这也是为什么很多人一开始用相对路径能显示,改了文章永久链接之后图片全部裂掉的原因。

所以,插图片这个事情,核心不在于标签语法,而在于先想清楚一个问题:你的图片最终部署后需要什么URL,你写的路径能不能映射到那个URL。路径、仓库目录、渲染规则,这三者必须对齐。下面几种方案其实都是在不同维度上解决这个对齐问题。

2. 本地插入图片的三种稳妥方式:从相对路径到资源文件夹

本地插入图片是大多数人最开始的选择。但"本地"也分好几种做法,我这里只说三种我认为最稳妥、也最容易复现的。

2.1 最简单粗暴的方法:统一放入source/images目录

在博客的source目录下建一个images文件夹,所有文章需要用的图片都往里面丢,文章里统一用根路径/images/文件名引用。例如图片放到了source/images/wechat-qr.png,文章里写:

![这是公众号二维码](/images/wechat-qr.png)

这个方案的好处是路径非常直观,部署之后URL就是域名/images/wechat-qr.png,不存在相对路径计算问题,也不会因为文章层级改变而裂图。缺点是随着文章越来越多,图片会全部堆在一起,命名冲突和管理混乱只是时间问题。如果图片很多,我会建议至少按年份或按主题分子目录,比如/images/2025/xx/。

它的本质是:图片作为全站静态资源存在,文章的URL和图片URL相互独立,靠绝对路径硬链接起来,所以永远不会有相对路径模糊匹配的问题。

2.2 官方推荐的姿势:开启post_asset_folder

Hexo一直有一个比较典型的"周边附件"机制,就是post_asset_folder。在根目录的_config.yml里设置post_asset_folder: true之后,每次执行hexo new post 标题,会自动生成一个和文章同名的文件夹,放在source/_posts/标题/下。文章里引用的图片放进这个专属文件夹,并通过官方提供的标签语法来引用,就能在渲染时自动配对到对应的文章URL。

开启方式很简单,找到_config.yml里的post_asset_folder配置项:

post_asset_folder: true

然后执行新建文章命令,就会生成同名文件夹:

hexo new post "怎么插入图片和视频"

生成后目录结构是这样:

source/_posts/ 怎么插入图片和视频.md 怎么插入图片和视频/ demo-pic.png

此时文章里推荐用官方的asset_img标签来引用:

{% asset_img demo-pic.png 这是配图说明 %}

而不是直接写标准的Markdown图片语法![](demo-pic.png)。原因是Hexo的官方标签在渲染时会自动根据文章的URL和资源文件夹的实际对应关系调整图片路径,避免手动计算层级。如果你直接写普通Markdown语法,文章本身虽然能渲染,但图片路径可能因为URL结构问题无法匹配。

我个人的建议是,只要你的文章图片数量不多、不把文章发到别的平台、也没有跨文章复用的需求,就用这个方案。它最大的价值是让每篇文章的图片跟随文章走,不会出现图库越滚越大、根本找不到哪张图属于哪篇文章的问题。

2.3 进阶一点:图片放本地,文章里用绝对链接引用

这种方案适合那些图片最终会上传到某个静态服务器或对象存储的人,但本地依然保留原始文件的场景。做法很简单:图片放本地source目录下的某个位置,比如source/uploads/文章别名/,但文章里不写相对路径,而是直接把最终部署后的完整链接地址写进去。

比如图片最终会上传到某个存储服务,URL是https://你的域名/uploads/article-cover.png,那文章里就直接写:

![文章封面](https://你的域名/uploads/article-cover.png)

这种方式的好处是写文章和最终发布解耦。你可以在本地进行预览、版本管理,但文章里用的是部署后的绝对URL,不存在本地预览和线上显示的差异问题。坏处是如果域名改了就全部失效,所以要么你的域名长期不变,要么就得用批量替换的方式去改。

这三种方式对比下来,路径一致性和长期可维护性是选择的核心。追求简单就用source/images,追求文章资源聚合就用post_asset_folder,追求部署解耦就用绝对链接。没有绝对的好,只有适不适合你的更新频率和部署习惯。

3. 图床和对象存储:当图片数量上来之后的选择

当文章量上来之后,本地图片方案会暴露出两个明显痛点:一是仓库体积越来越大,每次git clone或部署都变慢;二是图片分散在各篇文章里,做全站改造、换主题、迁移域名时非常痛苦。这时候上对象存储或者图床,是一个很自然的选择。

3.1 图和文字分离的好处

把图片和文字分离,本质上是把"内容"和"静态资源"两个生命周期分开管理。文章可以频繁修改、补充、纠错,但图片一旦上传,URL基本不再变化。这样迁移博客主题、更换部署平台时,文章里的图片引用完全不用动,只需把域名解析过来或者批量替换域名前缀。

另外,图片不进入Git仓库后,博客仓库的体积会小很多。我之前遇到过一次博客仓库膨胀到几百MB的情况,几乎全是图片历史版本造成的,后来把图片迁出后,仓库缩到了几十MB,克隆和部署都快了一大截。这个体感差异在换了新电脑、需要重新clone仓库时极为明显。

2.3 对象存储的基本流程

以主流的对象存储服务为例(不管哪家,流程大同小异):先在控制台创建存储桶,设置公共读权限或生成公开访问链接,然后通过客户端工具或网页上传图片,拿到图片的访问URL,再把URL直接贴在文章里。

关键配置有几点需要注意。第一,存储桶的读写权限。建议设为"公共读、私有写",保证图片可以被任何人通过URL访问,但只有你自己能上传删除。第二,绑定自定义域名。如果没有绑定,访问URL通常是平台自动生成的域名,一旦平台策略调整,域名可能变更,文章里的图片就会全部失效。绑定自定义域名后,URL就是https://图片子域名.你的域名/文件路径,更换平台时只需重新解析域名。第三,开启静态网站托管或对象存储的可访问index页面功能,这样直接访问目录路径时不会看到错误页。

这里是给一个非常典型的操作流程参考:

步骤操作内容说明
1创建存储桶地域选择离你主要访客最近的区域,读写权限选择公共读
2绑定自定义域名在存储服务的域名管理里绑定一个二级域名,并完成HTTPS证书配置
3配置上传工具推荐使用命令行工具或桌面客户端,配置AccessKey并指定默认上传路径
4上传图片用工具上传,拿到形如https://img.你的域名.com/2025/xx.png的URL
5文章引用直接在Markdown里使用完整URL

实测下来,这个方案最大的好处是彻底摆脱了"路径对齐"的烦恼,因为URL是死的。但对应的代价是你需要维护另外一套图片管理系统,上传、重命名、清理冗余图片都需要额外的习惯和规范。我个人的做法是给每个月的图片建一个按月命名的目录,文件名保持语义化,比如2025-06-cloud-native-deploy-cover.png,这样在存储桶里检索时也非常直观。

3.3 关于第三方图床的提醒

第三方图床是另一条路,也就是直接把图片传到一个专门提供图片托管服务的平台上,拿到外链。这个方案上手极快,不需要自己维护存储桶,但我个人并不建议把博客的核心图片放在这里。原因在于,图床服务的稳定性、访问速度、生命周期都不可控,一旦服务调整策略、关停或者图片被清理,你的博客会批量出现裂图。一次裂图几百张的体验,绝对会让你后悔当初图省事。

如果只是放文章封面预览、临时分享的图,那无所谓。但如果是长期使用的核心图片,还是建议至少放到自己能控制的对象存储里,或者干脆继续用本地加绝对链接的方案。博客最重要的是内容的可延续性,图片是内容的一部分,不能把命脉交到别人手里。

4. 视频插入的方案拆解:自托管与第三方平台嵌入

视频的插入方式跟图片不太一样,核心区别在于视频文件通常几十MB甚至几百MB,你不可能把它当作一般静态资源推到Git仓库,更不可能懒加载地放进文章里。所以视频方案从大的方向上分两类:一种是“视频文件本身自己保管”,另一种是“视频内容托管在第三方平台,文章里只放嵌入代码”。

4.1 本地自托管视频:直接放MP4,用HTML5的video标签

如果你视频尺寸不大、访问者数量可控,最简单的方案就是把MP4文件放到博客静态资源目录里,然后在文章里用HTML5的<video>标签引用。Markdown本身允许内嵌HTML,所以可以这样写:

<video controls preload="metadata" width="100%" poster="/images/video-cover.jpg"> <source src="/uploads/demo.mp4" type="video/mp4"> 你的浏览器不支持HTML5视频播放,请前往文章附属下载页观看。 </video>

这里面有几个细节需要注意。加了preload="metadata"之后,页面加载时不会立刻把整个视频文件下载下来,而只加载视频的元数据(时长、尺寸、首帧等),对文章页面的加载速度影响很小。controls属性会显示浏览器的原生播放控件,这个对绝大多数用户都够用了。poster提供一张封面图,避免视频区域在未播放前是一块难看的黑屏。type="video/mp4"能帮助浏览器提前判断是否支持该格式。

自托管视频最大的好处是:视频不经过任何第三方转码,你可以随意控制清晰度、码率、文件名和访问路径,也不存在平台审核或内容下架的问题。但缺点也很明显,就是流量和带宽的开销会压在你自己身上。如果博客放在普通的虚拟主机或GitHub Pages上,大视频文件不仅会拖慢页面加载速度,还可能被平台限制或拒绝。我一般建议自托管视频单个文件不要超过20MB,超过这个量级就优先考虑转码压缩或交给视频平台处理。

另外要注意移动端的适配。PC端浏览器对MP4的兼容性整体还行,但移动端部分浏览器对某些编码格式支持不稳定,建议输出H.264编码的MP4,不要用奇怪的编码格式。压视频的工具很多,我习惯用ffmpeg做一次基础压缩,命令大概是:

ffmpeg -i input.mp4 -vcodec h264 -acodec aac -movflags +faststart output.mp4

+faststart这个参数会把MP4的元数据移动到文件头部,让视频在浏览器端可以边下边播,而不是下载完整个文件才能播放。这个细节对网页内视频体验提升非常明显,强烈建议压完视频之后检查一下是否加了它。

4.2 第三方平台托管:用iframe嵌入而不是外链视频文件

对大多数博客来说,更实际的方案是把视频上传到某一视频平台,然后通过平台提供的嵌入代码放在文章里。嵌入的通用方式就是一个<iframe>标签,你只管粘贴对方提供的嵌入代码即可。

以通用的嵌入格式为例,大致是这样:

<iframe width="100%" height="400" src="https://视频平台嵌入地址/视频ID" frameborder="0" allowfullscreen></iframe>

这里有几个坑要提前讲。第一,很多视频平台的嵌入地址和播放页面地址不是一回事,不要直接在文章里链接到播放页面,那样会跳出去。你需要找到平台的“分享”或“嵌入”功能,那里会给出专门的iframe代码。第二,不同平台对嵌套的域名有限制,有的不允许在非认证网站里嵌入,有的则对自动播放做了限制。第三方平台嵌入的好处是流量消耗完全不在你这里,视频清晰度、播放器兼容性都是平台负责,你只需要关心嵌入代码本身。

第三,iframe的加载时机对页面性能影响很大。默认情况下,iframe会随着页面解析立刻加载视频播放器,这会让文章页面的体积和请求数大幅增加。如果你希望文章打开时页面更快,可以加loading="lazy"属性,让浏览器在iframe进入可视区域附近时才真正加载视频。这是一个很实用的小优化,代码变成:

<iframe loading="lazy" width="100%" height="400" src="视频嵌入地址" frameborder="0" allowfullscreen></iframe>

实测在图片较多的长文里,加上这个属性后首屏加载速度有明显提升,尤其移动端效果更明显。

4.3 文章内付费内容或私有视频的处理思路

如果你有一些不打算公开的视频,比如课程配套视频、某个小群体的内部演示,那就不能用上面的公开嵌入方案了。我能想到的可行路子要么是加密码保护的视频页面,要么是生成临时有效的访问链接。前者需要视频平台支持密码访问功能,后者通常需要借助存储服务的鉴权能力。

对象存储一般都有签名URL的功能,可以为文件生成一个带有效期的访问链接。比如设置为7天有效、限制IP或次数,然后把链接写在一个只有指定读者能看到的地方。这种方式灵活性很高,但需要在每次发布时手动生成链接,并且链接过期后读者可能忘了回复索要新的。这里没有特别完美的方案,我个人的建议是:如果视频内容持续更新,用支持密码功能的视频平台更省心;如果是一次性交付,用签名URL更简洁。两种方式都别把链接直接裸露在完全公开的页面里,否则等于没保护。

5. 图片和视频对博客性能的隐形拖累:体积优化与懒加载

很多博主把图片视频贴进文章后,就不再管它们了。实际上,页面加载速度和文章资源体积之间有非常直接的关系。博客不是复杂应用,往往就是图片视频拖慢了一切。

5.1 图片体积控制的几个基本手段

我说几个最基础但见效最快的做法。

第一,不要直接用手机或相机拍出来的原图。动辄几MB的图片放到网页上,对浏览速度是灾难。我一般会把图片压到100KB到300KB之间,保持清晰度的情况下能压多少压多少。推荐的工具是各种在线压缩服务或本地图片处理命令,比如用ffmpeg压缩图片也行,不过更常见的做法是用图片处理库批量处理。

第二,选择合适的格式。照片类图片用JPG,图标、截图、带文字的图片用PNG,如果读者浏览器普遍支持,可以尝试WebP或者AVIF,体积能进一步缩减。写博客不是做设计,清晰度只要肉眼看着不糊就行,没必要追求原图级的细节。

第三,合理设置图片的显示尺寸。很多人宽1000px的图片,在文章里其实只显示800px宽,图片文件本身的像素却还是3000px宽。浪费的体积全部变成了加载时间,而且压缩率越高,浪费越明显。建议先把图片尺寸调整到文章实际显示宽度的两倍以内,再做压缩。两倍是为了适配高分辨率屏幕,超过两倍意义就不大了。

第四,开启懒加载。Hexo主题大多数都集成了懒加载插件或者自带懒加载开关。如果没有,可以在图片标签里手动加loading="lazy"。加了之后,浏览器只有在图片接近可视区域时才加载图片,首屏速度会有肉眼可见的提升。这个属性是现代浏览器原生支持的,不需要额外引入JavaScript。

5.2 视频文件的压缩与公共CDN的存在意义

视频文件体积通常比图片大太多,所以压缩的必要性更突出。前面提到用ffmpeg压缩,这里再补充几个参数思路。视频分辨率不要超过文章容器实际宽度所需,比如文章区域最大宽度是800px,那720p就基本够用,1080p属于浪费。视频码率可以控制在2Mbps到4Mbps之间,具体看视频内容动态程度,动态少的长视频可以用更低码率。

+faststart参数前面已经说过,直接让MP4文件变成可流式播放。另外,视频的音频码率也可以适当降低,语音讲解类视频128kbps足够,音乐背景类稍微提高一点。

文件压缩完成后,如果你选择自托管,建议把这些视频文件放到对象存储上,再开启CDN加速。这里要解释一下CDN的意义:CDN会把你的视频文件缓存到离读者更近的节点上,下载速度会明显提升,同时源站的压力也减少了。没有CDN也不是不能用,但国内跨网访问、偏远地区访问时,源站直出的速度差异会非常明显。自托管视频加对象存储加CDN,是一种常见的静态资源组合方式,前提是你愿意付出一点配置成本。

5.3 让文章真正变"轻"的懒加载全家桶

除了图片和视频分别加懒加载,还有一些细节可以整体优化。比如给<video>标签的preload属性设成none或metadata,这样打开文章时,视频不会立刻下载。再比如,封面图可以用压缩过的小体积版本,视频本身等用户点击播放时才加载。这样文章页面的首屏资源就只剩文字和少量小图片,打开速度会非常接近纯文本页面。

还有一个小技巧:利用<picture>标签根据不同的屏幕尺寸加载不同分辨率的图片。不过这个对大部分博客来说有点过度设计了。如果你的读者分布中移动端占大多数,我建议至少做到图片体积控制和懒加载这两件事,效果已经很好了。

6. 实际发布中的常见翻车点:换主题丢图、部署后不显示、本地和线上不一致

最后说几个我实际踩过的坑,这些场景在操作顺利的时候根本想不到,但一旦遇到,排查思路要清晰。

6.1 换主题之后图片路径全废

换主题是博客生涯里几乎一定会发生的事。很多人以为换主题就是把主题文件夹换掉,结果一换之后,文章里的图片全部裂掉。原因其实不复杂:不同的主题,它对图片资源的目录约定不一样,对文章特有资源文件夹的处理方式也不一样。有的主题会启用post_asset_folder相关的路径改写,有的主题根本不处理。

我在换主题之前,会先做一次图片路径清单的梳理。用工具把所有文章里的图片引用全部列出来,然后对照新主题的静态目录结构,判断是否需要批量替换路径。如果图片全部放在source/images下,换主题的风险相对较低;如果之前用的是文章资源文件夹且引用了相对路径,换主题后几乎必然需要批量调整。

如果只是小范围修正,可以在Hexo的_config.yml里使用_post_asset_folder或者URL重写的方式来统一映射。如果图片很多,那就老老实实写一个批量替换脚本,一次性把文章里的旧路径替换成新路径。实际操作中,正则表达式可以帮上大忙,但前提是你在平时写文章时就保持图片路径格式的统一,否则脚本根本没法匹配。

6.2 部署后不显示,但本地预览正常——最容易被忽略的三个原因

这种场景排查起来比较抓狂,因为本地一切正常,线上就是不显示。通常原因有三个。

第一个是部署平台对文件名大小写敏感,而本地文件系统不敏感。比如你本地有个文件叫Demo.PNG,文章里写的是demo.png,本地可以正常访问,但部署到Linux服务器后,大小写不匹配就直接404。这种情况尤其容易出现在从Windows/Mac本地部署到Linux服务器的场景里。解决办法是统一用小写文件名,并且保持文章引用和实际文件名完全一致。

第二个是部署过程的缓存问题。有些平台缓存了旧版本的静态文件,导致你明明上传了新图片,线上访问的还是旧版或404。这时可以强制刷新CDN缓存,或者重新部署一次,过一段时间再看。

第三个是路径里包含了中文字符或特殊符号,导致生成的URL被编码处理,但文章里的链接还是原始字符。浏览器通常能自动编码,但某些旧版客户端或严格环境可能出现问题。最稳的做法是图片文件名和目录都不要用中文,只用英文、数字、中划线或下划线。

6.3 本地预览和线上显示不一致的排查顺序

当碰见本地能显示、线上不显示的怪异问题时,我建议按下面的顺序排查:

  1. 先看线上资源的URL地址是不是404,直接在浏览器里访问图片地址,确认文件是否存在。
  2. 对比线上URL和你文章里的引用路径,检查协议、域名、目录层级是否完全一致。
  3. 检查部署是否成功覆盖了旧文件,必要时清空缓存重新部署。
  4. 检查文件名的大小写和特殊字符问题。
  5. 最后检查主题或渲染插件是否对图片路径做了二次处理。

按这个顺序走下来,绝大多数问题都能定位到源头。大部分情况下都是路径不对或者文件名不匹配,真正出在线路、服务器配置上的状况反而很少。

7. 给长期维护博客的人几条实在建议:图片视频管理也是内容管理的一部分

写了这么多年博客,我越来越觉得,图片和视频不是文章写完之后才想起的附件,它们是内容本身的一部分。你插入一张示意图、一段演示视频,读者能不能顺利看到,直接决定了这篇文章的信息传达效率。所以长期维护博客,一定要把资源和文章同等对待。

我个人的管理习惯是这样的。图片能传对象存储就传对象存储,所有图片URL统一用自定义域名加规范路径;每篇文章的图片在文章开头就集中管理,不随手乱扔;图片文件名用语义化命名,并在文章里保持和文件名完全一致的引用。视频如果比较重要,就传到平台去做托管,用iframe嵌入;如果只是临时演示,就压缩到最小体积放在对象存储里自托管。每次换主题或改链接结构前,先导出所有文章的图片引用清单,做好路径变更预案。

这些做起来并不难,难的是养成习惯。但恰恰是这些习惯,决定了一个博客在运营一年、三年、五年之后,是依然清爽可用,还是变成一堆裂图满天飞的废墟。图片视频的插入技术本身没有多少高深的地方,真正拉开体验差距的,是持续而稳定的管理方式。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询