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

wp_ajax正常但wp_ajax_nopriv曾失效,咨询函数内获取私有JSON对象方法

问题描述

我正在为博客搭建搜索栏,登录状态下功能完全正常,但未登录时wp_ajax_nopriv失效,返回状态码200的空数组。目前已经通过wp_add_inline_script解决了这个问题,现在想咨询:有没有办法在PHP函数中获取私有JSON对象?

我的PHP代码

function get_ajax_posts() {
    $posts_d =array();
    // Query Arguments
    $args = array(
        'post_type' => 'custom_posts',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'order' => 'DESC',
        'orderby' => 'date',
    );

    // The Query
    $ajaxposts = new WP_Query($args); // changed to get_posts from wp_query, because `get_posts` returns an array
    if($ajaxposts->have_posts()){
        while($ajaxposts->have_posts()){
            $ajaxposts->the_post();
            array_push($posts_d, array(
                'title' => get_the_title(),
                'url'   => get_permalink()
            ));
        }
    }
    echo json_encode( $posts_d );

    exit; // exit ajax call(or it will return useless information to the response)
}

// Fire AJAX action for both logged in and non-logged in users
// add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');

wp_localize_script( 'hello-elementor-child-js', 'script',
            array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );

我的JavaScript代码

jQuery('#s').on('keyup',function(){
  $ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>"
    jQuery.ajax({
      type: 'POST',
      dataType: "json", // add data type
      // url: script.ajax_url,
      url: $ajaxurl,
      data: { action : 'get_ajax_posts' },
      success: function( response ) {
          var jobs = '';
          var count = 0;
          var text = jQuery('#s').val().toLowerCase();
          if (!arr || arr.length === 0){
            var arr = jQuery(response.filter(function(value){
              text = text || null;
              return value.title.toLowerCase().includes(text);
            }))
          };
          jQuery.each( arr, function( key, value ) {
            if (count == 5){
              return false;
            } else {
              jobs += '<a href="' + value.url + '"><p>' + value.title + '</p></a>';
              count++;
            }
            } );
            jQuery('#livesearch').html(jobs);
      }
    });
    });
解决方案

1. 直接在PHP函数中读取私有JSON文件

如果私有JSON对象存在服务器本地文件中,可直接在get_ajax_posts函数里读取解析:

function get_ajax_posts() {
    // 读取私有JSON文件(路径要准确,文件权限设为仅服务器可读,比如600)
    $json_file_path = get_stylesheet_directory() . '/private-data.json';
    $private_data = [];
    if (file_exists($json_file_path)) {
        $private_json = file_get_contents($json_file_path);
        $private_data = json_decode($private_json, true);
        // 这里可直接使用$private_data做后续处理
    }

    // 原有业务逻辑...
    $posts_d = array();
    $args = array(
        'post_type' => 'custom_posts',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'order' => 'DESC',
        'orderby' => 'date',
    );
    $ajaxposts = new WP_Query($args);
    if($ajaxposts->have_posts()){
        while($ajaxposts->have_posts()){
            $ajaxposts->the_post();
            array_push($posts_d, array(
                'title' => get_the_title(),
                'url'   => get_permalink()
            ));
        }
    }
    // 若需要,可把私有数据合并到返回结果中
    // $posts_d['private_data'] = $private_data;
    echo json_encode( $posts_d );
    exit;
}

2. 前端传递私有标识,后端匹配获取JSON

如果私有数据需要先传到前端,再通过AJAX请求带回后端处理:

  • 第一步,在PHP中通过wp_localize_script传递私有标识:
wp_localize_script( 'hello-elementor-child-js', 'script',
    array(
        'ajax_url' => admin_url( 'admin-ajax.php' ),
        'private_key' => 'your_unique_private_key' // 或加密后的JSON片段
    )
);
  • 第二步,在JS的AJAX请求中携带该标识:
jQuery.ajax({
    type: 'POST',
    dataType: "json",
    url: script.ajax_url,
    data: { 
        action : 'get_ajax_posts',
        private_key: script.private_key
    },
    // 原有success逻辑...
});
  • 第三步,在PHP函数中接收并匹配私有数据:
function get_ajax_posts() {
    $private_data = [];
    if (isset($_POST['private_key'])) {
        $private_key = sanitize_text_field($_POST['private_key']);
        // 根据标识从数据库/配置文件读取对应私有JSON
        $private_data = get_private_data_by_key($private_key);
    }

    // 原有业务逻辑...
    echo json_encode( $posts_d );
    exit;
}

额外:排查wp_ajax_nopriv空数组的潜在问题

虽然你已经解决了空数组问题,还是可以做下检查:

  • 确认custom_posts自定义文章类型的注册参数中,public设为true、exclude_from_search设为false,确保未登录用户能查询到该类型文章。
  • 在WP_Query的参数中添加'suppress_filters' => true,避免其他插件/主题修改查询结果:
$args = array(
    'post_type' => 'custom_posts',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'order' => 'DESC',
    'orderby' => 'date',
    'suppress_filters' => true
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:45:33