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

WordPress AJAX调用中如何获取当前产品页的产品ID

问题原因

WordPress的AJAX请求全部走/wp-admin/admin-ajax.php统一入口,这个请求和你当前浏览的产品详情页是完全独立的PHP执行流程,产品页里初始化的global $product、$post这类全局变量根本不会自动传到AJAX回调里,直接在回调函数里调全局变量当然拿不到值。另外你原来的代码里WP_Query循环也用$product当循环变量,就算真拿到了全局产品对象也会被覆盖,本身写法就有坑。

实现步骤

1. 前端发请求时把当前页的产品ID一起传过去

AJAX本身不会自动带当前页面的上下文数据,你得在页面渲染阶段就把产品ID准备好,跟着请求参数传给后端。
首先改JS代码,加个参数接收当前产品ID:

jQuery(document).ready(function($) {
    var data = {
        'action': 'get_product_list',
        'current_product_id': typeof window.currentProductId !== 'undefined' ? window.currentProductId : 0
    };

    jQuery.post("/wp-admin/admin-ajax.php", data, function(response) {
        console.log(response);
    });
});

然后在主题functions.php里加个钩子,只在产品详情页把当前产品ID输出到页面JS里,非产品页不会输出这个变量,JS会默认传0:

add_action('wp_footer', 'output_current_product_id_for_js');
function output_current_product_id_for_js() {
    if (function_exists('is_product') && is_product()) {
        global $product;
        echo '<script>window.currentProductId = ' . esc_js($product->get_id()) . ';</script>';
    }
}

如果你是用wp_enqueue_script加载的JS,不想用全局变量,也可以用wp_localize_script把产品ID绑到你的JS对象上,逻辑完全一样,本质都是在页面生成的时候把ID打在前端,跟着请求走。

2. 后端AJAX回调接收参数使用

修改你原来的回调函数,先从请求里取前端传的ID,做安全校验之后就能正常用了:

add_action('wp_ajax_get_product_list', 'get_product_list');
add_action('wp_ajax_nopriv_get_product_list', 'get_product_list');
function get_product_list()
{
    // 接参数,强制转整数做安全校验,避免非法输入
    $current_product_id = isset($_POST['current_product_id']) ? intval($_POST['current_product_id']) : 0;

    $args = array(
        'post_type'      => 'product',
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'orderby'        => 'name',
        'order'          => 'ASC'
    );

    $loop = new WP_Query($args);
    $allProducts = '';

    // ID大于0就说明请求来自产品详情页
    if ($current_product_id > 0) {
        // 在这里写你需要的当前产品逻辑就行,要拿产品对象就用wc_get_product($current_product_id)
        $current_product = wc_get_product($current_product_id);
    }

    // 这里循环变量别用$product,避免和全局对象冲突
    foreach ($loop->posts as $product_item) {
        $selected_attr = ($product_item->ID == $current_product_id) ? 'selected' : '';
        $allProducts .= '<option value="' . $product_item->ID . '" ' . $selected_attr . '>' . esc_html($product_item->post_title) . '</option>';
    }

    wp_reset_query();

    echo $allProducts;
    wp_die();
}
避坑提醒
  • 别尝试靠解析请求的referer头、匹配页面url的方式拿产品ID,固定链接结构改了、装个缓存插件就容易失效,稳定性极差
  • 所有前端传过来的参数一定要做格式校验,这里直接转int就行,避免安全问题
  • 不要在WP_Query循环里用$product当临时变量,很容易覆盖全局的产品对象导致其他逻辑出问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:24:29