静态博客没有服务器,搜索从哪来?答案是:把索引交给浏览器。一个 JS 文件、一个输入框、两百行代码,就能换来体面的全文搜索——而且零请求、零后端、零隐私成本。

01先建立索引

把每篇文章的元数据——标题、双语摘要、栏目、关键词——集中到一个独立的 JS 文件里。页面加载时,索引就绪:

window.BLOG_POSTS = [
  {
    slug: "static-search",
    title: "没有后端的搜索",
    titleEn: "Search Without a Backend",
    excerpt: "把索引交给浏览器……",
    keywords: "search 搜索 索引 index"
  }
  // …更多文章
];

用 JS 数组而不是 fetch JSON,还有一个现实的好处:双击本地文件(file://)也能运行。Chrome 会拦截本地 JSON 请求,但不会拦截一个普通的 script 标签。

02过滤与高亮

搜索逻辑可以简单得惊人:把输入按空白分词,每个词都必须命中(AND 语义),命中的位置用 <mark> 标红:

function search(terms){
  return posts.filter(p => {
    const hay = [p.title, p.titleEn, p.excerpt,
                 p.excerptEn, p.keywords].join(' ');
    return terms.every(t => hay.toLowerCase().includes(t));
  });
}

再配一个 120ms 的防抖,输入时不会反复重算;按回车直接跳转到第一条结果。全部加起来,就是本站搜索页的全部秘密。

03权衡与边界

这套方案适合几百篇以内的站点。中文没有天然分词,包含匹配会漏掉「网格」与「格子」这样的词形变化——所以我在索引里加了一个 keywords 字段来兜底。文章再多、对检索质量要求更高时,可以换 Lunr 或 Fuse.js,甚至用构建期生成倒排索引。

没有服务器的搜索,是静态网站最后的优雅。

想试试?打开本站的搜索页,输入「网格」或「grid」——它正在你的浏览器里,本地为你工作。