将工作线程与WordPress Nonce(自定义wp-api端点)一起使用

时间:2018-11-21 14:07:29

标签: javascript wordpress wordpress-rest-api

我正在为WordPress构建一个插件,该插件必须对自定义WP API端点进行大量的ajax请求。无法以异步方式处理请求,因此必须使用Worker线程来防止浏览器在处理过程中挂起。到目前为止,还没有那么复杂,但是我想使用WordPress随机数进行验证。当我做工人时,我是这样做的:

worker = new Worker("worker.js");

这可以正确加载工作程序,但是现在我想谈谈我们的自定义Ajax端点。因此,需要通过wp_enqueue_script加载脚本,以便对随机数进行验证(我在这里正确吗?)。

wp_enqueue_script('itw_admin_update_products', plugins_url('assets/js/worker.js', __FILE__), [ 'jquery', 'wp-api' ], '1.0', true );

以上使它偏离航向负载两次。如何在仍能验证Ajax端点处的随机数的同时将脚本作为工作程序加载?

1 个答案:

答案 0 :(得分:0)

我自己弄清楚了:

注册REST路由

register_rest_route('my-rest-route/v1', '/rest-action', array(
    'methods' => 'GET',
    'callback' => 'callback-function',
    'permission_callback' => function () { return current_user_can('edit_pages'); },

使脚本入队

wp_localize_script()函数传递了我们需要加载工作程序并告诉工作程序应在哪里进行请求的变量。 wp_enqueue_script()确保脚本在正确的时间加载,并允许向API端点发出请求。

$params = array(
    'jsWorker'      => plugins_url('assets/js/the-worker.js', ITW_BASEDIR . '/ipp-to-woo.php'),
    'rest_route'    => get_rest_url(null, 'my-rest-route/v1/rest-action'),
);
wp_register_script('the_handler', plugins_url('assets/js/the-script.js', __FILE__), [ 'jquery', 'wp-api' ], '1.0', true );
wp_localize_script('the_handler', 'the_object', $params);
wp_enqueue_script('the_handler');

从the-script.js呼叫工作人员

因为我们使用了wp_localize_script()将变量传递给客户端,所以我们现在可以使用the_object.jsWorker来加载工作程序。加载worker后,我们将传递一个带有worker.postMessage的对象,该对象包含API端点和WordPress生成的现时值以验证自己。

worker = new Worker(the_object.jsWorker);
worker.addEventListener('message', function(e) {
    var response
    response = JSON.parse(e.data)

    processResponse(response);

});

worker.postMessage({'nonce': wpApiSettings.nonce, 'url': the_object.rest_route});

从the-worker.js进行Ajax调用

最后但并非最不重要的一点,在the-worker.js中,我们使用xhr.setRequestHeader像Wordpress一样来验证自己。

function doAjaxCall(url, nonce){
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, false);
        xhr.setRequestHeader( 'X-WP-Nonce', nonce );
        xhr.onload = function() {
        if (xhr.status === 200) {
            self.postMessage(xhr.response);
        }
    };
    xhr.send();
}

self.addEventListener('message', function(e) {
    var data = e.data;
    self.doAjaxCall(data.url, data.nonce);
}, false);