使用Fetch API的WP-admin AJAX无需用户即可完成

时间:2017-01-16 作者:ojrask

TL;DR - 为什么在wp admin内部发出的AJAX请求期间,我的用户帐户没有登录?

我有以下设置:

<?php

add_action(\'wp_ajax_foobar_action\', \'foobar_action\');
add_action(\'wp_ajax_nopriv_foobar_action\', \'foobar_action\');

function foobar_action() {
    check_ajax_referrer();

    wp_send_json((object) [\'msg\' => \'hello world\']);
}

add_action(\'admin_print_scripts\', function () {
    printf(\'<script type="text/javascript">window.custom_nonce = "%s";</script>\', wp_create_nonce());
});
在JS中:

var msg = \'\';

// I\'m using the whatwg-fetch polyfill and a polyfill for Promises.
fetch(ajaxurl, {
    method: \'POST\',
    headers: {
        \'Content-Type\': \'application/x-www-form-urlencoded; charset=utf-8\'
    },
    body: \'action=foobar_action&_wpnonce=\' + window.custom_nonce
}).then(function (res) {
    msg = res.json().msg;
});
这都是在wp admin中运行的。问题是wp admin page/JS脚本本身是作为登录用户加载的,但AJAX请求最终会加载到admin AJAX中。php是作为注销的来宾用户完成的。这导致了使用wp admin的问题noprivcheck_ajax_referrer 百分百失败。

为什么wp admin以来宾身份而不是登录用户的身份发出AJAX请求?

当前,AJAX端点返回403 状态为-1 内容,以防出现nonce不匹配。如果我把check_ajax_referrer() 调用,然后AJAX请求成功运行。愤怒之后console.log我已经确定,在JS fetch调用中,nonce值与接收它的AJAX端点相匹配(这意味着nonce已正确传输,但在AJAX端点执行期间生成了错误的来宾nonce)。

如果我删除wp_ajax_nopriv_foobar_action 然后WordPress找不到启用身份验证的AJAX操作,因为似乎没有可用的登录用户(导致状态为200 和车身0).

我尝试解决此问题的步骤:

注销并再次登录,清除缓存/cookie,使用匿名windows,重新启动PHP-FPM、Nginx、对象缓存后端、MariaDB,禁用所有操作不需要的插件,将AJAX挂接代码在我的插件代码中移动,一直移动到插件根文件(例如。myplugin/myplugin.php),

2 个回复
SO网友:ojrask

在与@t-todua进行了一些磨蹭和争论之后,我发现了问题:

使用Fetch APIfetch 呼叫您必须手动设置为随请求发送Cookie。在设置credentials 选项正确发送cookie,AJAX端点识别当前用户。因此JS变成:

var msg = \'\';

// I\'m using the whatwg-fetch polyfill and a polyfill for Promises.
fetch(ajaxurl, {
    method: \'POST\',
    headers: {
        \'Content-Type\': \'application/x-www-form-urlencoded; charset=utf-8\'
    },
    body: \'action=foobar_action&_wpnonce=\' + window.custom_nonce,
    credentials: \'same-origin\'
}).then(function (res) {
    msg = res.json().msg;
});

SO网友:T.Todua

我认为问题可能是由于以下后果:

在HTML源中,首先应输出:.......... window.custom_nonce = "%s" ... 然后应该打电话fetch 作用在里面foobar_action(), 添加此行:var_dump(is_user_logged_in()); 请看,可能它检测到登录(如果是,那么原因是暂时的。否则,问题是login)

p、 你们有并没有试过换个帖子来获取方法?

相关推荐

如何全局使用wp_LOCALIZE_SCRIPT()AJAX URL

我已将此添加到functions.php 并且需要使用ajaxURL 在模板中的所有排队脚本中(而不是在此处仅将一个脚本排队add_action( \'wp_enqueue_scripts\', \'ajaxify_enqueue_scripts\' ); function ajaxify_enqueue_scripts() { wp_localize_script( \'ajaxify\', \'ajaxURL\', array(\'ajax_url\' => get_tem