You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React调用WordPress自定义API POST请求失败问题排查

这个问题的核心确实是CORS(跨域资源共享)的预检请求处理不当,尤其是针对www.example.com这个Origin的POST请求。GET请求属于简单请求,不需要发送OPTIONS预检,所以能正常通过;而POST请求(如果携带了Content-Type这类非简单请求头)会先发送OPTIONS预检,服务器如果没正确响应这个请求,浏览器就会拦截后续的POST请求。

下面是一步步的解决思路:

1. 修复WordPress REST API的CORS响应头

WordPress默认的REST API CORS处理可能只允许了单个Origin,你需要手动添加对两个域名的支持。可以在主题的functions.php或者自定义插件里添加以下代码:

add_action( 'rest_pre_serve_request', function( $serve_request ) {
    // 允许的两个域名
    $allowed_origins = [
        'https://example.com',
        'https://www.example.com'
    ];
    
    $request_origin = isset( $_SERVER['HTTP_ORIGIN'] ) ? $_SERVER['HTTP_ORIGIN'] : '';
    
    if ( in_array( $request_origin, $allowed_origins ) ) {
        // 动态匹配请求来源,设置允许的Origin
        header( "Access-Control-Allow-Origin: {$request_origin}" );
        // 允许的请求方法
        header( 'Access-Control-Allow-Methods: GET, POST, OPTIONS' );
        // 允许的请求头(根据你的Axios请求调整,Content-Type是必须项)
        header( 'Access-Control-Allow-Headers: Content-Type' );
        // 如果请求需要携带凭证(比如登录Cookie),必须开启这个
        header( 'Access-Control-Allow-Credentials: true' );
    }
    
    return $serve_request;
} );

这段代码会在每个REST API请求发送前,检查请求的Origin是否在允许列表里,然后返回对应的CORS头。

2. 检查服务器层面的CORS配置(Nginx/Apache)

有时候服务器的配置会覆盖WordPress返回的响应头,所以需要确保服务器也正确处理CORS:

如果你用Nginx:

在你的站点配置里添加针对API路径的规则:

location ~ ^/wp/wp-json/game {
    # 处理OPTIONS预检请求
    if ($request_method = OPTIONS) {
        add_header Access-Control-Allow-Origin $http_origin;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
        add_header Access-Control-Allow-Headers "Content-Type";
        add_header Access-Control-Allow-Credentials "true";
        return 204; # 预检请求不需要返回内容
    }
    
    # 处理正常的GET/POST请求
    add_header Access-Control-Allow-Origin $http_origin;
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
    add_header Access-Control-Allow-Headers "Content-Type";
    add_header Access-Control-Allow-Credentials "true";
    
    # 保留原有的WordPress转发规则
    try_files $uri $uri/ /wp/index.php?$args;
}

如果你用Apache:

在站点的.htaccess文件里添加:

<IfModule mod_headers.c>
    # 匹配example.com和www.example.com
    SetEnvIf Origin "https://(www\.)?example\.com" AccessControlAllowOrigin=$0
    # 动态设置允许的Origin
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header add Access-Control-Allow-Methods "GET, POST, OPTIONS"
    Header add Access-Control-Allow-Headers "Content-Type"
    Header add Access-Control-Allow-Credentials "true"
</IfModule>

3. 调整Axios的请求配置

如果你的POST请求需要携带凭证(比如用户登录状态的Cookie),必须在Axios里开启withCredentials:

// 全局配置,所有请求生效
axios.defaults.withCredentials = true;

// 或者单个POST请求单独配置
axios.post('https://example.com/wp/wp-json/game/check_answer', yourData, {
    withCredentials: true
});

同时,要确保WordPress设置的Cookie的Domain是.example.com(注意前面的点),这样www.example.com和example.com都能共享这个Cookie。你可以通过WordPress的钩子调整:

add_filter( 'setcookie_params', function( $params ) {
    $params['domain'] = '.example.com';
    return $params;
} );

4. 验证预检请求

打开浏览器开发者工具(F12),切换到Network面板,筛选OPTIONS请求,查看www.example.com下的预检请求:

  • 状态码应该是204
  • 响应头里必须包含Access-Control-Allow-Origin: https://www.example.com
  • 同时要有Access-Control-Allow-Methods和Access-Control-Allow-Headers

如果预检请求失败,浏览器就不会发送后续的POST请求,这就是你看到“无响应”的直接原因。

5. 可选:统一域名(从根源解决)

如果不想维护双域名的CORS配置,可以把www.example.com永久重定向到example.com(或者反过来),这样所有请求都来自同一个Origin,彻底避免跨域问题。

比如Nginx的重定向配置:

server {
    listen 443 ssl;
    server_name www.example.com;
    
    # 重定向到不带www的域名
    return 301 https://example.com$request_uri;
}

内容的提问来源于stack exchange,提问作者Danny Hobo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:07:34