WordPress Ajax筛选返回400错误,请求代码排查解决
WordPress Ajax筛选文章返回400错误排查
我在WordPress中开发了一个简易的Ajax筛选文章功能,折腾3天了,Ajax仍持续返回400错误,以下是相关代码及错误信息,恳请帮忙排查:
一、相关代码
1. HTML/PHP结构代码
<?php $categories = get_categories(); ?> <ul class="cat-list"> <li><a class="cat-list_item active" href="#" data-slug="">All projects</a></li> <?php foreach($categories as $category) : ?> <li> <a class="cat-list_item" href="#" data-slug="<?= $category->slug; ?>" data-type="projecten"> <?= $category->name; ?> </a> </li> <?php endforeach; ?> </ul> <?php $projects = new WP_Query([ 'post_type' => 'customer_stories', 'posts_per_page' => -1, 'tax_query' => [ [ 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $termIds, // 示例 $termIds = [4,5] 'operator' => 'IN' ], ] ]); ?> <?php // 查询 $the_query = new WP_Query( $args ); // 循环输出 if ( $the_query->have_posts() ) { echo '<ul>'; while ( $the_query->have_posts() ) { $the_query->the_post(); echo '<li>' . esc_html( get_the_title() ) . '</li>'; } echo '</ul>'; } else { esc_html_e( 'Sorry, no posts matched your criteria.' ); } // 恢复原始文章数据 wp_reset_postdata(); ?>
2. Ajax处理函数
function filter_projects() { // 验证nonce if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'theme_ajax_nonce') ) { wp_send_json_error('Invalid nonce'); exit; } // 安全获取POST参数 $postType = isset($_POST['type']) ? sanitize_text_field($_POST['type']) : ''; $catSlug = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : ''; $args = [ 'post_type' => 'customer_stories', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'desc', ]; // 如果分类slug不为空,添加分类查询 if ( !empty($catSlug) ) { $args['category_name'] = $catSlug; } $ajaxposts = new WP_Query($args); $response = ''; if($ajaxposts->have_posts()) { while($ajaxposts->have_posts()) : $ajaxposts->the_post(); $response .= get_template_part( 'src/page-modules/project-list-item.php' ); endwhile; } else { $response = 'empty'; } wp_reset_postdata(); // 恢复原始文章数据 echo $response; exit; } add_action('wp_ajax_filter_projects', 'filter_projects'); add_action('wp_ajax_nopriv_filter_projects', 'filter_projects');
3. 原始JavaScript代码
(function($){ $.ajax({ type: 'POST', url : wpajax.url, dataType: 'html', data: { action: 'filter_projects', category: $(this).data('slug'), type: $(this).data('type'), }, success: function(res) { $('.project-tiles').html(res); } }); WP_enqueue })(jQuery);
4. 脚本注册代码
<?php // 主题CSS & JS function base_scripts_styles() { $in_footer = true; $ver = 1; // 加载功能脚本 wp_enqueue_script( 'base-script', get_template_directory_uri() . '/dist/js/main.js', array( 'jquery' ), $ver, $in_footer ); wp_enqueue_script( 'theme-script', get_template_directory_uri() . '/theme.js', array( 'jquery' ), $ver, $in_footer ); wp_enqueue_script( 'ajax', get_template_directory_uri() . '/inc/ajax_script.js', array( 'jquery' ), $ver, $in_footer ); // 加载样式 wp_enqueue_style( 'base-main', get_template_directory_uri() . '/dist/css/main.css', array(), $ver ); wp_enqueue_style( 'base-style', get_stylesheet_uri(), array(), $ver ); // 本地化脚本,传递Ajax参数 wp_localize_script( 'ajax', 'wpajax', array( 'url' => admin_url( 'admin-ajax.php'), 'nonce' => wp_create_nonce( 'theme_ajax_nonce' ), 'searchButton' => esc_attr( __( 'Search', 'base' ) ), ) ); wp_register_script( 'lottie-player', 'https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js', array(), $ver ); } add_action( 'wp_enqueue_scripts', 'base_scripts_styles' ); function theme_add_admin_styles() { wp_enqueue_style( 'admin_css', get_template_directory_uri() . '/admin-style.css', false, '' ); } add_action( 'admin_enqueue_scripts', 'theme_add_admin_styles' );
二、错误信息
JavaScript控制台错误
jquery-3.6.0.min.js:2 Uncaught Error: Syntax error, unrecognized expression: #! at se.error (jquery-3.6.0.min.js:2:13639) at se.tokenize (jquery-3.6.0.min.js:2:21650) at se.select (jquery-3.6.0.min.js:2:22477) at Function.se [as find] (jquery-3.6.0.min.js:2:7116) at S.fn.init.find (jquery-3.6.0.min.js:2:25047) at new S.fn.init (jquery-3.6.0.min.js:2:25536) at S (jquery-3.6.0.min.js:2:1051) at l.t [as getAnchorTarget] (main.js?ver=1:3:153334) at HTMLAnchorElement.<anonymous> (main.js?ver=1:3:153137) at jquery-3.6.0.min.js:2:24485
三、问题排查与修复方案
1. 修复wp_localize_script参数错误
原脚本注册代码中wp_localize_script多传了两个无效参数'base-script'和'themeAjax',该函数仅接受3个参数:脚本handle名、全局变量名、数据数组,删除多余参数后即可正确传递wpajax变量。
2. 添加Nonce验证(解决400错误核心)
WordPress的admin-ajax.php默认需要Nonce验证,未提交或验证失败会直接返回400错误:
- PHP端:在Ajax处理函数开头添加Nonce验证逻辑
- JS端:在Ajax请求的
data中加入nonce: wpajax.nonce
3. 修正JS中$(this)的指向问题
原JS代码直接执行Ajax,$(this)并非点击的分类标签,需要绑定a标签的点击事件,将Ajax逻辑放入回调函数中,同时阻止默认跳转行为:
(function($){ $('.cat-list_item').on('click', function(e){ e.preventDefault(); // 阻止a标签默认跳转 $.ajax({ type: 'POST', url : wpajax.url, dataType: 'html', data: { action: 'filter_projects', nonce: wpajax.nonce, // 添加nonce验证 category: $(this).data('slug'), type: $(this).data('type'), }, success: function(res) { $('.project-tiles').html(res); // 可选:切换active类 $('.cat-list_item').removeClass('active'); $(this).addClass('active'); }.bind(this), // 绑定this指向,让success里的this指向当前点击的a标签 error: function(xhr){ console.log(xhr.responseText); // 打印错误信息便于排查 } }); }); })(jQuery);
4. 修复a标签href="#!"的jQuery选择器错误
jQuery无法解析#!作为锚点选择器,将href="#!"改为href="#"或href="javascript:void(0)",同时配合e.preventDefault()阻止默认跳转,避免页面滚动到顶部。
5. 增强Ajax处理函数的安全性与健壮性
- 使用
isset()检查POST参数是否存在,避免未定义索引警告 - 使用
sanitize_text_field()过滤用户输入,防止XSS等安全问题 - 添加
wp_reset_postdata()恢复原始文章数据,避免后续查询出错
内容的提问来源于stack exchange,提问作者Beep
相关产品推荐
相关产品推荐

