为受限访问的 WordPress 站点构建搜索模态框

大多数 WordPress 搜索教程都过于简单。它们只是告诉你把一个组件丢进页眉里。这对于公开博客有效,但对于会员制网站却行不通。

如果你拥有付费课程或私密视频,默认的搜索功能可能会导致数据泄露。它会向未登录用户显示私密内容的标题,这会破坏你的付费墙。

我使用 WordPress、WooCommerce 和 LearnDash 为一个健身网站构建了一个自定义搜索模态框。以下是如何构建遵循访问规则的搜索功能。

架构设计

我使用了一个统一的索引,而不是为每种内容类型进行单独搜索。这使我能够在查询层面实施访问限制。

搜索结果遵循以下规则:

  • 博客文章是公开的。
  • 点播视频是受限的。
  • 课程通过 LearnDash 进行权限控制。
  • 商店产品是公开的。

我在子主题中构建了一个自定义 REST 路由。我避免使用代码片段插件,以确保搜索功能的稳定性。

关键工程细节

服务端权限控制:永远不要使用 JavaScript 来隐藏结果。如果你在浏览器端隐藏结果,数据仍然存在于网络响应中。用户可以通过 DevTools 看到它。你必须在数据离开服务器之前在服务端进行过滤。

缓存管理:如果你缓存了搜索结果,可能会将会员的私密结果展示给陌生人。请将你的搜索 REST 路由从页面缓存中排除,以防止泄露。

优雅降级:在调用 Relevanssi 等第三方插件时,请使用保护机制(guards)。如果插件失效,搜索应该回退到 WordPress 核心搜索功能,而不是导致网站崩溃。

性能优化:使用防抖函数(debounce,250ms)和 AbortController。这可以防止浏览器在每次按键时都发送新请求。它还能取消旧请求,从而避免过期数据覆盖新结果。

安全性:在使用 innerHTML 之前,务必对字符串进行转义(escape)。这可以防止恶意文章标题引发的 XSS 攻击。

移动端经验教训

我曾苦于一个页面构建器(page builder)将我的搜索按钮“吞”进了移动端菜单里。我尝试了许多 CSS 修复方法,但都失败了。

解决方案很简单:不要与主题硬碰硬。我没有把按钮放在菜单内部,而是将其作为一个独立的元素注入到页眉中。如果某个组件抗拒你的修改,那就把它放在该组件旁边,而不是里面。

最佳实践总结:

  • 在服务端实施访问控制。
  • 将搜索端点从缓存中排除。
  • 使用 debounce 和 AbortController 以获得流畅的 UX。
  • 转义所有 API 数据以防止 XSS。
  • 将元素放置在顽固的主题容器之外。

来源:https://dev.to/highcenburg/building-a-search-modal-for-a-membership-gated-wordpress-site-b92