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
相关产品推荐
相关产品推荐

