WordPress Headless API 前后端分离教程

Headless CMS 是现代 Web 开发的重要趋势。WordPress 作为后端内容管理系统提供 API 接口,前端使用 React、Vue 或 Next.js 等框架独立渲染页面。这种架构既保留了 WordPress 强大的内容管理能力,又能利用现代前端技术获得更好的性能和用户体验。本文将在搬瓦工 VPS 上演示完整的 Headless WordPress 搭建方案。

一、WordPress REST API 基础

WordPress 从 4.7 版本开始内置了完整的 REST API。默认端点为 /wp-json/wp/v2/

1.1 常用 API 端点

# 获取文章列表
curl https://your-domain.com/wp-json/wp/v2/posts

# 获取单篇文章
curl https://your-domain.com/wp-json/wp/v2/posts/1

# 获取页面列表
curl https://your-domain.com/wp-json/wp/v2/pages

# 获取分类目录
curl https://your-domain.com/wp-json/wp/v2/categories

# 获取标签
curl https://your-domain.com/wp-json/wp/v2/tags

# 获取媒体文件
curl https://your-domain.com/wp-json/wp/v2/media

# 带参数查询
curl "https://your-domain.com/wp-json/wp/v2/posts?per_page=10&page=1&_embed&categories=5"

1.2 注册自定义 API 端点

在 functions.php 中注册自定义 REST API 路由:

// 注册自定义端点
function my_custom_api_routes() {
    register_rest_route('mytheme/v1', '/featured-posts', array(
        'methods'  => 'GET',
        'callback' => 'get_featured_posts',
        'permission_callback' => '__return_true',
    ));
}
add_action('rest_api_init', 'my_custom_api_routes');

function get_featured_posts($request) {
    $args = array(
        'posts_per_page' => 5,
        'meta_key'       => 'featured',
        'meta_value'     => '1',
    );
    $posts = get_posts($args);
    $data = array();
    foreach ($posts as $post) {
        $data[] = array(
            'id'        => $post->ID,
            'title'     => $post->post_title,
            'excerpt'   => get_the_excerpt($post),
            'thumbnail' => get_the_post_thumbnail_url($post->ID, 'medium'),
            'link'      => get_permalink($post),
        );
    }
    return new WP_REST_Response($data, 200);
}

1.3 API 认证配置

对于需要写入操作的 API 请求,需要配置认证。安装 Application Passwords 或 JWT 认证插件:

# 安装 JWT 认证插件
wp plugin install jwt-authentication-for-wp-rest-api --activate --allow-root

wp-config.php 中添加 JWT 密钥:

define('JWT_AUTH_SECRET_KEY', '你的随机密钥字符串');
define('JWT_AUTH_CORS_ENABLE', true);

在 Nginx 配置中传递 Authorization 头:

# 确保 Authorization 头被正确传递给 PHP
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTP_AUTHORIZATION $http_authorization;
}

二、WPGraphQL 配置

GraphQL 相比 REST API 更灵活,可以精确查询所需数据,避免过度获取。

2.1 安装 WPGraphQL

wp plugin install wp-graphql --activate --allow-root

安装后,GraphQL 端点默认为 /graphql。可以在后台"GraphQL > Settings"中访问 GraphiQL IDE 进行查询测试。

2.2 GraphQL 查询示例

# 使用 curl 发送 GraphQL 查询
curl -X POST https://your-domain.com/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ posts(first: 10) { nodes { id title date excerpt featuredImage { node { sourceUrl } } categories { nodes { name slug } } } } }"
  }'

2.3 扩展 GraphQL Schema

// 在 functions.php 中注册自定义字段到 GraphQL
add_action('graphql_register_types', function() {
    register_graphql_field('Post', 'viewCount', [
        'type'        => 'Int',
        'description' => '文章浏览次数',
        'resolve'     => function($post) {
            return (int) get_post_meta($post->ID, 'view_count', true);
        }
    ]);
});

三、CORS 跨域配置

前后端分离架构中,前端和后端通常部署在不同域名或端口,需要配置 CORS:

3.1 Nginx 层面配置 CORS

# 在 Nginx server 块中添加
location /wp-json/ {
    add_header 'Access-Control-Allow-Origin' 'https://frontend.example.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;

    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 86400;
        add_header 'Content-Length' 0;
        return 204;
    }

    try_files $uri $uri/ /index.php?$args;
}

location /graphql {
    add_header 'Access-Control-Allow-Origin' 'https://frontend.example.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;

    if ($request_method = 'OPTIONS') {
        return 204;
    }

    try_files $uri $uri/ /index.php?$args;
}

3.2 WordPress 层面配置 CORS

// 在 functions.php 中添加
function add_cors_headers() {
    $origin = get_http_origin();
    $allowed_origins = array(
        'https://frontend.example.com',
        'http://localhost:3000',
    );
    if (in_array($origin, $allowed_origins)) {
        header("Access-Control-Allow-Origin: $origin");
        header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
        header("Access-Control-Allow-Headers: Authorization, Content-Type");
        header("Access-Control-Allow-Credentials: true");
    }
}
add_action('rest_api_init', function() {
    remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
    add_filter('rest_pre_serve_request', function($value) {
        add_cors_headers();
        return $value;
    });
});

四、Next.js 前端对接

4.1 创建 Next.js 项目

# 安装 Node.js(如果还没有安装)
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install nodejs -y

# 创建 Next.js 项目
npx create-next-app@latest wp-frontend --typescript --app
cd wp-frontend

4.2 配置 API 客户端

创建 lib/wordpress.ts

// lib/wordpress.ts
const API_URL = process.env.WORDPRESS_API_URL || 'https://your-domain.com';

export async function getPosts(page = 1, perPage = 10) {
  const res = await fetch(
    `${API_URL}/wp-json/wp/v2/posts?page=${page}&per_page=${perPage}&_embed`,
    { next: { revalidate: 60 } }
  );
  if (!res.ok) throw new Error('获取文章失败');
  return res.json();
}

export async function getPost(slug: string) {
  const res = await fetch(
    `${API_URL}/wp-json/wp/v2/posts?slug=${slug}&_embed`,
    { next: { revalidate: 60 } }
  );
  const posts = await res.json();
  return posts[0] || null;
}

4.3 使用 PM2 部署前端

# 构建生产版本
npm run build

# 安装 PM2
npm install -g pm2

# 使用 PM2 启动
pm2 start npm --name "wp-frontend" -- start
pm2 save
pm2 startup

4.4 Nginx 反向代理前端

server {
    listen 80;
    listen 443 ssl http2;
    server_name frontend.example.com;

    ssl_certificate /etc/letsencrypt/live/frontend.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/frontend.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
    }
}

五、Headless WordPress 优化

5.1 禁用前端主题渲染

在 Headless 模式下,WordPress 不再渲染前端页面,可以禁用主题加载以提升 API 响应速度:

// 将前端访问重定向到 API 或前端应用
function redirect_to_frontend() {
    if (!is_admin() && !defined('DOING_AJAX') && !defined('REST_REQUEST') && !defined('GRAPHQL_REQUEST')) {
        wp_redirect('https://frontend.example.com', 301);
        exit;
    }
}
add_action('template_redirect', 'redirect_to_frontend');

5.2 API 响应缓存

// 为 REST API 添加缓存头
function add_api_cache_headers($response) {
    $response->header('Cache-Control', 'public, max-age=300');
    return $response;
}
add_filter('rest_post_dispatch', 'add_api_cache_headers');

总结

WordPress Headless 架构将内容管理和前端展示解耦,充分发挥各自的优势。WordPress 负责内容创作和管理,现代前端框架负责高性能的页面渲染。在搬瓦工 VPS 上,你可以将 WordPress 后端和 Next.js 前端部署在同一台服务器上,也可以分别部署在不同的 VPS 上实现更好的隔离。更多 WordPress 教程请参考 插件配置指南速度优化指南。选购搬瓦工 VPS 请查看 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣,通过 bwh81.net 进入官网购买。

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。