我最近一直在研究ajax。您在网上找到的教程都很相似并且很容易实现。
但是我总是在ajax-admin.php文件上收到400错误的请求。

经过长时间的深入搜索,我发现现在发现这是因为集成的时间。

如果我使用init动作钩子初始化脚本和wp_localize_script,那么一切正常。因此,代码本身必须正确。

my-page-test-functions.php

function ajax_login_init(){
   wp_register_script('ajax-login-script',get_stylesheet_directory_uri().'/js/ajax-login-script.js',array('jquery'));
   wp_enqueue_script('ajax-login-script');
   wp_localize_script('ajax-login-script','ajax_login_object',array('ajaxurl' => admin_url('admin-ajax.php'),'redirecturl' => 'REDIRECT_URL_HERE','loadingmessage' => __('Sending user info, please wait...')));
   add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');
}

if(!is_user_logged_in()){
   add_action('init','ajax_login_init');
}

function ajax_login(){
    //nonce-field is created on page
    check_ajax_referer('ajax-login-nonce','security');
    //CODE
    die();
}


但是如果我使用例如wp_enqeue_scripts动作挂钩我总是接到错误的请求。

if(!is_user_logged_in()){
    add_action('wp_enqueue_scripts','ajax_login_init');
}


问题是:

我想将函数包含在多余的php文件,仅在特定页面上需要它们时才加载它们。为此,例如,我需要is_page()
但是,当我将函数与包含到is_page()操作钩中的函数挂钩时,parse_query最早可以工作:

functions.php

function sw18_page_specific_functions(){
    if(is_page('page-test')){
        include_once dirname(__FILE__).'/includes/my-page-test-functions.php';
    }
}

add_action('parse_query','sw18_page_specific_functions');


因此,我想,钩在init文件中的my-page-test-functions.php钩子上的函数不会触发,因为initparse_query之前。

是否有组织此最佳实践,这样有效吗?还是在使用admin-ajax.php操作钩时如何解决wp_enqeue_scripts错误的请求?

#1 楼

我认为这里唯一缺少的是您需要将add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');移到ajax_login_init之外。

该代码注册了您的Ajax处理程序,但是当仅在wp_enqueue_scripts上运行它时,它已经来不及了,并且wp_ajax_nopriv_钩子已经存在运行。

所以,您是否尝试过这样的操作:

function ajax_login_init(){
  if ( ! is_user_logged_in() || ! is_page( 'page-test' ) ) {
    return;
  }

  wp_register_script('ajax-login-script',get_stylesheet_directory_uri().'/js/ajax-login-script.js',array('jquery'));
  wp_enqueue_script('ajax-login-script');
  wp_localize_script('ajax-login-script','ajax_login_object',array('ajaxurl' => admin_url('admin-ajax.php'),'redirecturl' => 'REDIRECT_URL_HERE','loadingmessage' => __('Sending user info, please wait...')));
}

add_action( 'wp_enqueue_scripts','ajax_login_init' );

add_action( 'wp_ajax_nopriv_ajaxlogin','ajax_login' );

function ajax_login(){
  //nonce-field is created on page
  check_ajax_referer('ajax-login-nonce','security');
  //CODE
  die();
}


编辑:

现在更清楚了您只想在该特定页面上加载JavaScript。这意味着您需要将is_page()放入ajax_login_init()中。我已经相应地更新了代码。

现在,为什么您的解决方案不起作用?

is_page()检查意味着您的功能文件仅在该特定页面上加载。 ajax_login_init()被调用,您的脚本入队。到目前为止一切顺利。

现在您的脚本进行了ajax调用。如评论中所述,ajax调用不知道您当前所在的页面。该文件位于wp-admin/admin-ajax.php的原因是有原因的。没有WP_Query,因此is_page()在ajax请求期间不起作用。

由于这不起作用,因此sw18_page_specific_functions()在ajax上下文中不会做任何事情。这意味着您的函数文件没有被加载并且ajax处理程序不存在。

这就是为什么您需要始终包含该函数文件并在is_page()中移动该ajax_login_init()检查的原因。
因此,直接运行sw18_page_specific_functions() { … }而不是include_once dirname(__FILE__).'/includes/my-page-test-functions.php';。没有任何add_action( 'parse_query' )通话。

评论


好建议。我已经更改了该错误(仍然是相同的错误),但是问题仍然是包含函数的文件加载得太晚了。但是我需要一种方法来区分使用哪个页面。 -目前,如上所述,我使用is_page()尝试了此操作。

–罪
18年1月17日在11:04

您是要从ajax_login()还是ajax_login_init()内部运行is_page()。前者无法工作,因为它处于Ajax上下文中。

–swissspidy
18年1月17日在12:05

我已将函数所在的文件枚举为上面的描述性文字。 is_page()在functions.php中使用,仅在需要时用于将文件包含在ajax函数中。

–罪
18年1月17日在12:48

@Sin再次,is_page()在Ajax上下文中不起作用。我已经相应更新了我的答案。

–swissspidy
18年1月17日在12:58

#2 楼

请记住在wp_ajax_标签上附加了“动作”功能名称。

function fetchorderrows() { // Want to run this func on ajax submit
  // Do awesome things here all day long
}

add_action('wp_ajax_fetchorderrows', 'fetchorderrows', 0);


#3 楼

如果有人使用基于类的方法并遇到ajax 400问题,则可能需要将ajax句柄移到类之外(在主插件文件中尝试),并在第二个参数中使用类和方法。
add_action( 'wp_ajax_your_handle', [ 'Class_Name', 'function_name' ] );
add_action( 'wp_ajax_nopriv_your_handle', [ 'Class_Name', 'function_name' ] );


评论


无需将这些移出课堂。只需将它们挂接到admin_init,以便在管理ajax请求时执行它们。

– Erenor Paz
20 Dec 18 '14:50



#4 楼

写死吧最后像下面这样...

评论


嗨Zee Xhan。欢迎来到该网站。您的答案需要一些修改。首先,如果您的答案是代码,请不要发布屏幕截图。而是将代码作为摘要发布,并将其格式化为代码(使用{}按钮)。这可能是您的答案被否决并且未被接受的原因。另外,多一点解释将是有帮助的-例如“为什么”只写die(),这相对于OP中的代码到底在哪里?

– Butlerblog
18年11月12日在14:46