CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
WordPress 开发入门/课时/AJAX 与 Headless
RawBlame
课时目录12 节

WordPress 开发入门

  1. 01WordPress 概览
  2. 02环境搭建
  3. 03主题开发
  4. 04区块编辑器
  5. 05插件生态
  6. 06Hooks 与 CPT
  7. 07PHP 架构
  8. 08数据库
  9. 09AJAX 与 Headless
  10. 10安全加固
  11. 11性能与运维
  12. 12综合练习

AJAX 与 Headless

REST、Cron 与 Settings API。

30 分钟

REST API 与 Headless(WP + Next.js)

这一课你将能做到

  1. 消费 WP 内置 REST API(列表、详情、分页、_fields/_embed),并说清三种认证方式
  2. 用 register_rest_route 自建带 permission_callback 的自定义端点
  3. 用本站同款 Next.js App Router 把 WP 当 Headless CMS:SSG 静态化 + ISR 增量更新

为什么要学

传统 WP 的前台由 PHP 主题渲染;Headless 模式把前台换成 Next.js——WP 只当内容仓库和编辑后台。这正是本站 java-nav 的架构思路:编辑在后台改内容,前端用 SSG/ISR 渲染,CDN 直接回静态页,性能与安全面同时受益。

人话:把 WP 想成一个自带后台的内容数据库,/wp-json/ 就是它的查询窗口。Next.js 在构建期把窗口里的数据「烤」进静态页面,编辑一发文,ISR 到点自动重烤——内容与展示彻底解耦。

先建立图像

编辑者 → WP 后台(文章/课程CPT) → MySQL
                       ↓
              REST /wp-json/wp/v2/...        ← 数据出口
                       ↓ 服务端 fetch
Next.js (app router)
  build 时: generateStaticParams → 烤出全部课程详情页(SSG)
  运行时: revalidate=300 → ISR 每 5 分钟后台重验证
                       ↓
        Vercel/Node 服务 → CDN → 用户浏览器

对比传统 WP:请求每次都打到 PHP+MySQL;Headless 下绝大多数用户请求根本不碰 WP。

跟着做

步骤 1:消费内置端点

# 列表:只取需要的字段,减小载荷
curl -s "http://localhost:8080/wp-json/wp/v2/posts?per_page=3&_fields=id,title,slug,link"

# 分页信息在响应头:X-WP-Total(总数) / X-WP-TotalPages
curl -s -I "http://localhost:8080/wp-json/wp/v2/posts" | grep -i x-wp

# 详情按 slug 取
curl -s "http://localhost:8080/wp-json/wp/v2/posts?slug=hello-world&_fields=title,content"

_fields 精简返回、_embed 一次带出作者/特色图等关联——这两个参数决定前端体验。

步骤 2:自建一个聚合端点

插件中注册:

add_action( 'rest_api_init', function () {
    register_rest_route( 'qrocmq/v1', '/courses', array(
        'methods'             => WP_REST_Server::READABLE,
        'permission_callback' => '__return_true',   // 公开只读;写操作必须校验能力
        'args'                => array(
            'level' => array(
                'type'              => 'string',
                'enum'              => array( 'beginner', 'advanced' ),
                'sanitize_callback' => 'sanitize_key',
            ),
        ),
        'callback'            => function ( WP_REST_Request $request ) {
            $query = new WP_Query( array(
                'post_type'      => 'course',
                'post_status'    => 'publish',
                'posts_per_page' => 20,
                'meta_query'     => array(
                    array(
                        'key'   => 'level',
                        'value' => $request->get_param( 'level' ) ?? '',
                        'compare' => '!=',
                    ),
                ),
            ) );
            $items = array_map(
                fn( WP_Post $p ): array => array(
                    'id'    => $p->ID,
                    'title' => get_the_title( $p ),
                    'slug'  => $p->post_name,
                    'level' => get_post_meta( $p->ID, 'level', true ),
                ),
                $query->posts
            );
            return rest_ensure_response( $items );
        },
    ) );
} );

验证:curl -s "http://localhost:8080/wp-json/qrocmq/v1/courses?level=advanced"。命名空间 qrocmq/v1 与核心的 wp/v2 隔离。

步骤 3:认证方式三选一

# 1) Application Passwords(推荐,6.x 内置):后台 用户→个人资料→应用密码 生成
curl -s -u "admin:xxxx xxxx xxxx xxxx xxxx xxxx" \
     "http://localhost:8080/wp-json/wp/v2/users/me"

# 2) 浏览器内已登录:Cookie + wp_rest nonce(同域前端)
// 前端: fetch(url, { credentials: 'include', headers: { 'X-WP-Nonce': QROCMQ_CFG.nonce } })

# 3) JWT 插件:适合跨域移动端/微服务,需配 CORS

原则:服务端到服务端用 Application Passwords;浏览器同域交互用 Cookie+nonce;跨系统用 JWT 并收紧白名单。

步骤 4:Next.js 前台(本站同款写法)

app/courses/page.tsx(列表):

type Course = { id: number; title: string; slug: string; level: string };

export const revalidate = 300;   // ISR:5 分钟增量再生

async function getCourses(): Promise<Course[]> {
    const res = await fetch(
        `${process.env.WP_API_URL}/wp-json/qrocmq/v1/courses`,
        { next: { revalidate: 300, tags: ['courses'] } }
    );
    if ( ! res.ok ) return [];
    return res.json();
}

export default async function CoursesPage() {
    const courses = await getCourses();
    return (
        <ul>
            { courses.map( ( c ) => (
                <li key={ c.id }>
                    <a href={ `/courses/${ c.slug }` }>{ c.title } · { c.level }</a>
                </li>
            ) ) }
        </ul>
    );
}

app/courses/[slug]/page.tsx(详情,SSG):

export async function generateStaticParams() {
    const res = await fetch( `${process.env.WP_API_URL}/wp-json/qrocmq/v1/courses` );
    const courses = await res.json();
    return courses.map( ( c: { slug: string } ) => ( { slug: c.slug } ) );
}

export async function generateMetadata( { params }: { params: Promise<{ slug: string }> } ) {
    const { slug } = await params;
    const course = await getCourse( slug );     // 复用 fetch 逻辑
    return { title: course?.title ?? '课程详情' };
}

步骤 5:让「发文 → 前端更新」联动

两条路任选或叠加:ISR 到点自动重验证(上面的 revalidate);编辑发布时 WP 侧发 webhook,Next.js 收到后调用 revalidateTag( 'courses' )(on-demand revalidation),实现秒级生效。

讲清楚要点

  1. permission_callback 是安全底线:从 WP 5.x 起省略它即默认公开;写操作必须校验 current_user_can(),公开端点只读。
  2. 参数三件套:type/enum 约束、sanitize_callback 清洗、default 兜底——REST 层的输入验证在这里完成。
  3. Headless 的收益与代价:收益是前端自由(React 生态)、性能可控(CDN 静态)、攻击面缩小(只暴露只读 API);代价是失去主题生态、编辑预览与表单要自建、运维两条线。
  4. 缓存分层决定一致性:WP 对象缓存/页面缓存 + Next 数据缓存/全路由缓存 + CDN,任何一层都可能让「发文不生效」——排查顺序从 CDN 往里剥。
  5. 本站选型逻辑:java-nav 内容更新频率低、SEO 要求高 → SSG 打底 + ISR 增量是性价比最高的组合,无需为实时性上 SSR。

你可能会懵的地方

  • 跨域调用 REST 被 CORS 拦? 浏览器直连才有 CORS 问题。本站做法是 Next.js 服务端 fetch(Node 到 Node 无 CORS);确需浏览器直连,才配置 rest_pre_serve_request 过滤器或代理。

  • nonce 什么时候需要? 只在「浏览器内已登录用户」发起写请求时用(防 CSRF)。匿名公开读、服务端用 Application Passwords 的场景,都不需要 nonce。

  • X-WP-Total 为什么在 body 里拿不到? 分页统计放在响应头。前端要总数就先 HEAD 或读 header;Next.js 里 res.headers.get('x-wp-total')。

  • 发文了 Next 页面没更新? 按层排查:WP 端缓存(WP-CLI 清)、Next 数据缓存(revalidate/webhook)、CDN 缓存(清缓存或降 TTL)。确认 WP API 直出已是新数据,再往前找。

  • 媒体文件怎么处理? 图片仍存 WP uploads,REST 返回 wp:featuredmedia(配合 _embed)。Next 用 next/image 加 remotePatterns 白名单 WP 域名,享受压缩与懒加载。

错法对照

错法问题正解
register_rest_route 不写 permission_callback默认公开,写接口等于裸奔读可公开、写必校验能力
前端组件里存 WP 管理员账密密钥泄露服务端环境变量 + Application Passwords
在浏览器直连 WP 拉全量字段载荷大 + CORS服务端 fetch + _fields 精简
所有页面都用 SSR 实时打 WPWP 成瓶颈SSG+ISR,写操作才考虑 SSR
端点一次返回全站数据载荷爆炸分页 + X-WP-Total + 按需字段

卡点急救

  1. 404 自定义命名空间:路由没生效时重访一次「设置→固定链接」(刷新 rewrite 规则)即可。
  2. 401 rest_forbidden:permission_callback 返回了 false——核对你的能力检查与登录态;跨域时检查 cookie 是否带上。
  3. Next 构建期 fetch 失败:构建环境访问不到 WP(内网/自签证书),把 WP_API_URL 配成可达地址或改为运行时获取。

面试常问

  • 设计一个 Headless WP + Next.js 架构,你会怎么选渲染策略? 内容型页面 SSG 打底(generateStaticParams)+ ISR(revalidate 或 webhook 按需重验证);用户相关内容客户端请求只读端点;搜索等强实时页面可 SSR。理由:SEO、性能、WP 负载三者平衡。

  • REST API 的三种认证方式和适用场景? Cookie+wp_rest nonce(浏览器内已登录用户,防 CSRF);Application Passwords + Basic Auth(服务端间调用,可吊销);JWT(跨域/移动端,需自管过期与 CORS)。

  • 发文后前端多久生效?怎么做到秒级? 取决于缓存层:默认 ISR 到点重验证;接入 WP webhook → Next revalidateTag 即按需失效,秒级生效;CDN 层再按路径定向清除。

自测三问

  1. register_rest_route 的哪个参数决定端点是否公开?写端点还必须做什么?
  2. _fields 和 _embed 分别解决什么问题?
  3. SSG、ISR、SSR 三者的取舍标准是什么?本站选哪种,为什么?

小结一句话

WP 在 Headless 架构里只做「内容仓库 + 编辑后台」,REST 是唯一出口;Next.js 用 SSG+ISR 把出口数据烤成 CDN 可缓存的页面——这就是本站同款的前后端解耦方案。

延伸

  • WP REST API 官方手册
  • Next.js 数据获取与缓存
  • 下一课:安全加固——nonce、转义、防注入与一次完整的生产加固。
加载本节练习…
← 上一课数据库下一课 →安全加固