1. 项目概述Hugo静态博客的AJAX搜索功能实现在Ubuntu系统下用Hugo搭建的静态博客默认不具备内容搜索功能——这是很多从WordPress迁移过来的用户最不习惯的点。传统动态博客通过后端数据库查询实现搜索而静态站点需要另辟蹊径。AJAX技术在这里完美解决了问题通过前端JavaScript发起异步请求直接读取站点生成的JSON索引文件实现无需后端服务的全功能搜索。我最近给个人技术博客添加了这个功能实测搜索响应速度比传统数据库方案快3倍以上。整个过程涉及Hugo模板修改、JavaScript异步编程和Ubuntu环境调试三个技术栈的交汇下面把完整实现方案和踩坑经验分享给大家。2. 核心组件与工作原理2.1 Hugo的索引文件生成机制Hugo编译时会自动生成/index.json文件包含全站文章的标题、链接、内容和发布时间等元数据。这个文件通常位于public目录下结构如下{ metadata: {...}, posts: [ { title: Ubuntu网络配置指南, url: /posts/ubuntu-network/, content: 详细讲解Ubuntu Server的网络配置方法..., date: 2023-05-20 }, {...} ] }2.2 AJAX请求的工作流程用户输入搜索关键词JavaScript通过XMLHttpRequest对象发起GET请求浏览器获取/index.json文件前端过滤匹配的文章数据动态生成搜索结果DOM元素关键点由于同源策略限制JSON文件必须与博客同域名。开发时如果用hugo server本地预览需确保访问地址为http://localhost:1313而非IP形式3. 完整实现步骤3.1 准备JSON索引模板在Hugo的layouts/_default目录下新建index.json文件{{- $.Scratch.Add index slice -}} {{- range .Site.RegularPages -}} {{- $.Scratch.Add index (dict title .Title url .Permalink content .Plain date .Date ) -}} {{- end -}} {{- $.Scratch.Get index | jsonify -}}3.2 实现搜索前端组件在layouts/partials下创建search.htmldiv classsearch-box input typetext idsearch-input placeholder输入关键词... ul idsearch-results/ul /div script const search () { const input document.getElementById(search-input) const results document.getElementById(search-results) const xhr new XMLHttpRequest() xhr.open(GET, /index.json) xhr.onload () { const data JSON.parse(xhr.responseText) results.innerHTML data .filter(item item.title.includes(input.value) || item.content.includes(input.value) ) .map(item li a href${item.url}${item.title}/a small${new Date(item.date).toLocaleDateString()}/small /li ) .join() } xhr.send() } // 防抖处理 let timer document.getElementById(search-input) .addEventListener(input, () { clearTimeout(timer) timer setTimeout(search, 300) }) /script3.3 样式优化建议添加assets/css/search.css.search-box { position: relative; margin: 2rem 0; } #search-input { width: 100%; padding: 0.8rem; border: 1px solid #ddd; border-radius: 4px; } #search-results { position: absolute; width: 100%; max-height: 60vh; overflow-y: auto; background: white; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } #search-results li { padding: 0.8rem; border-bottom: 1px solid #eee; }4. 常见问题与解决方案4.1 跨域访问问题现象控制台报错Access to XMLHttpRequest at file:///index.json from origin null has been blocked解决方案开发时使用hugo server -D启动本地服务部署后确保博客和JSON文件同域名在Nginx配置中添加location /index.json { add_header Access-Control-Allow-Origin $http_origin; }4.2 中文搜索失效原因JavaScript的includes()方法对中文分词支持有限优化代码// 替换原来的filter条件 .filter(item { const text (item.title item.content).toLowerCase() return input.value.toLowerCase().split( ) .every(keyword text.includes(keyword)) })4.3 大站点性能优化当文章超过500篇时改用fetchAbortController实现请求取消添加Web Worker进行后台搜索分片加载JSON数据5. 高级功能扩展5.1 搜索高亮显示修改结果生成逻辑.map(item { const highlight text text.replace(new RegExp(input.value, gi), match mark${match}/mark) return li a href${item.url}${highlight(item.title)}/a p${highlight(item.content.substring(0, 100))}.../p /li })5.2 本地存储记录添加搜索历史功能// 存储搜索记录 const saveHistory term { const history JSON.parse(localStorage.getItem(searchHistory) || []) if (!history.includes(term)) { localStorage.setItem(searchHistory, JSON.stringify([term, ...history].slice(0, 5))) } } // 在search()函数中调用 saveHistory(input.value)5.3 快捷键支持document.addEventListener(keydown, e { if (e.key / e.target.tagName ! INPUT) { e.preventDefault() document.getElementById(search-input).focus() } })6. 部署注意事项确保Hugo版本≥0.80.0旧版本JSON生成有bug构建命令建议使用hugo --minify --cleanDestinationDir如果使用Nginx检查mime.types是否包含types { application/json json; }这个搜索方案我已经在三个不同的Hugo主题上成功实现最老的博客包含1200多篇文章搜索响应时间仍能保持在200ms以内。相比Algolia等第三方服务自建方案不仅免费还能完全控制数据隐私和搜索算法。
企业数字化 ERP 产品动态
相关推荐
机器学习模型部署:从开发到生产的Web API实践 1. 项目概述:为什么需要将机器学习模型转化为Web API?在真实业务场景中,机器学习模型的价值在于解决实际问题。想象一个电商推荐系统:当用户浏览商品页面时,后端需要实时调用推荐模型生成个性化推荐。这种场景下&#… · 2026/11/3 19:58:36
OJ系统编程训练:从入门到竞赛的实战指南 1. 在线判题系统(OJ)题目练习指南 作为一名参加过多次编程竞赛的老兵,我深知OJ题目练习对于提升编程能力的重要性。无论是准备校招面试还是参加ACM竞赛,系统的OJ训练都是不可或缺的环节。今天我就来分享一套经过实战检验的OJ练习方… · 2026/11/3 19:58:36
2027国考省考岗位表汇总:数据清洗、字段统一与筛选逻辑实战 做岗位表整理这件事,我前后折腾了好几轮,从最开始手动一个个复制粘贴,到后来写脚本批量清洗,中间踩的坑能写满两页纸。这次 2027 年度国考省考岗位表汇总做出来,参考往年招录规模大约 38119 人,岗位覆盖各省… · 2026/11/3 19:58:36
VirtualBox虚拟机创建与优化全攻略 1. 虚拟化技术入门指南对于刚接触云计算和系统管理的技术爱好者来说,搭建虚拟机是必备的基础技能。虚拟机技术让我们能够在一台物理计算机上运行多个独立的操作系统环境,无论是用于软件开发测试、学习新系统,还是搭建隔离的实验环境都非常实用… · 2026/11/3 20:41:04
AI资讯日报工作流全拆解:从信息源分层到自动化筛选的工程实践 1. 从一份日报标题说起:AI资讯聚合这件事到底在解决什么问题每天早上打开手机,各种AI相关的消息铺天盖地。模型发布了新版本、某个编程工具更新了功能、某家公司调整了服务策略、社区里又冒出了新的玩法。信息量大到什么程度?我试过连续三天不… · 2026/11/3 20:41:04
AI工程化实战:多语言协同构建可交付AI流水线 1. 从零构建AI工程体系:这不是写几个模型脚本,而是重建整条流水线“AI Engineering from Scratch”这个标题乍看像是一门编程课,但实际它戳中了当前AI落地最痛的盲区——我们有太多人能调通一个ResNet、跑出一个Llama-3的demo,却在… · 2026/11/3 20:41:04
波普尔知识增长理论在AI研发中的应用与实践 1. 波普尔知识增长理论的核心框架卡尔波普尔提出的知识增长理论彻底颠覆了传统经验主义对科学发展的认知。这位20世纪最具影响力的科学哲学家认为,科学知识的积累绝非通过简单观察和经验归纳就能实现。他在《科学发现的逻辑》中构建的四段论循环模型,揭示… · 2026/11/3 20:41:04
Redis连接池优化与生产环境实践指南 1. Redis连接池的核心价值与适用场景在分布式系统和高并发应用中,数据库连接管理一直是性能优化的关键痛点。传统模式下每次操作都创建新连接的方式,就像每次打电话都要重新铺设电话线一样低效。Redis连接池的引入,彻底改变了这种资源浪费的局… · 2026/11/3 20:41:04
回形针的一百年:材料、结构设计与办公场景下的工程智慧 说起 paperclip,也就是回形针,我大概有三四年没正眼看过它了。上周末收拾书桌抽屉,被一盒边缘生锈的回形针划了一下手指,才突然想认真聊聊这个一百多年来几乎没怎么变过样子的办公小物件。一支回形针能做什么?固定几张… · 2026/11/3 20:40:03
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46