仅使用wp_enqueue_scripts操作钩子对admin-ajax.php的400错误请求


16

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

经过长时间深入的搜索,我现在发现这是由于集成时间所致。

如果我使用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文件的函数不会触发,因为init是在之前parse_query

是否有最佳实践来组织此操作,使其有效?或者admin-ajax.php在使用wp_enqeue_scripts动作挂钩时如何解决错误的请求?

Answers:


13

我认为,这里唯一缺少的就是您需要搬到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()尝试了此操作。
Sin

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

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

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


-3

写死吧 像下面这样在此处输入图片说明


8
嗨Zee Xhan。欢迎来到该网站。您的答案需要一些修改。首先,如果您的答案是代码,请不要发布屏幕截图。而是将代码作为摘要发布,并将其格式化为代码(使用{}按钮)。这可能是您的答案被否决并且未被接受的原因。另外,多一点解释将是有帮助的-例如“为什么”只写die(),这相对于OP中的代码到底在哪里(原始帖子)?
butlerblog
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.