Определение того, является ли это вызовом AJAX из внешнего интерфейса или из внутреннего


Я разрабатываю плагин только для администратора, который использует некоторые вызовы ajax в своем интерфейсе. Сам веб-сайт также полагается на вызовы ajax на своем интерфейсе.

Я хотел бы иметь возможность определить, когда WP загружается из-за "простого внутреннего вызова", "внутреннего вызова AJAX" или "внешнего вызова AJAX". Вариант использования, в простейшей форме, может заключаться в загрузке моего плагина только на страницы администратора или вызовы ajax с них. Кроме того, это помогает не ломать интерфейс при разработке на живой сайт:)

До сих пор я нашел следующее:

  • is_admin() возвращает значение true при всех вызовах AJAX (что странно, имхо)
  • поскольку все мои вызовы AJAX выполняются с помощью jQuery, я могу определить вызов AJAX по переменной HTTP HTTP_X_REQUESTED_WITH (см. здесь).

Но я все еще не могу понять, как отличить AJAX на стороне администратора от AJAX на лицевой стороне. Есть какие-нибудь идеи?

 1
Author: Aurimas, 2011-10-09

3 answers

Я понимаю вашу проблему, я думал о том же самом.

На самом деле это не проблема, это скорее вопрос хорошего дизайна программирования и хорошего разделения интерфейсной и серверной части.

Теперь мне удалось решить эту проблему следующим образом:

Я надеюсь, что вы вызываете свое действие AJAX с помощью wp_localize_script. Мы собираемся немного расширить это, реализовав его следующим образом:

wp_localize_script(
    'my-site-script',
    'my_ajax_object',
    array(
        'my_ajax_url' => admin_url( 'admin-ajax.php' ),
        'my_frontend_call' => 'something-here',
        'my_nonce' => wp_create_nonce( 'my_nonce' )
);

Это добавлено ТОЛЬКО на первой странице, я уверен, ты знаешь, как это работает. Теперь, как вы знаете, это добавит небольшой фрагмент javascript. Обратите внимание здесь на переменную my_frontend_call, это важная переменная, которую мы собираемся использовать.

Дополнительные инструкции о том, как настроить хороший вызов ajax здесь: ссылка

Теперь у нас все настроено, теперь мы можем легко реализовать логику в бэкэнде следующим образом:

<?php
// Here we check that we are facing the backend.
// This will also be true if we are facing the 
// frontend but making an AJAX call. 
// As you say bad, also IMO
if( is_admin() )
{
        //Now here we are going to put the magic
        if(isset($_POST['my_frontend_call'])){
            // Now these actions are loaded only when `my_frontend_call` is set
            // You can add everything here that only get's loaded on a call where
            // `my_frontend_call` is set
            add_action('wp_ajax_handle_frontend_ajax', 'handle_frontend_ajax_callback');
            add_action('wp_ajax_admin_only_ajax', 'admin_only_ajax_callback');
        }
}

Теперь вы можете немного смешать это с разными переменными из разных мест.

Я не знаю, почему это не известная рекомендация. На мой взгляд, это некрасиво, когда вещи загружаются, когда они даже не нужны.

ПРИМЕЧАНИЕ Я все еще новичок в WordPress, так что, возможно, это не очень хороший метод, я надеюсь, что некоторые профессионалы здесь смогут прокомментировать это.

 1
Author: Saif Bechan, 2011-11-12 20:45:36

is_admin() возвращает значение true при всех вызовах AJAX (что странно, imho)

В этом нет ничего странного, потому что вызовы Ajax следуют гораздо большей логике загрузки администратора, чем интерфейсный интерфейс. По сути, загрузка Ajax - это специализированная версия загрузки администратора.

В простейшей форме вариантом использования может быть загрузка моего плагина только на страницы администратора или вызовы ajax с них.

Не уверен, что вы здесь имеете в виду. Очередь сценариев не зависит от Ajax. Если вы не хотите, чтобы сценарий был включен передний конец - не загружайте его туда.

Современный WordPress не полагается на рефереры и тому подобное для определения того, откуда поступил вызов, вместо этого для проверки источника и намерения следует использовать nonces.

Поскольку это ваш собственный код, то проще всего отличить запрос от запроса, чтобы он содержал явный аргумент с информацией, идет ли он спереди или сзади.

 1
Author: Rarst, 2011-10-09 20:56:20
is_admin() returns always true whether it is from back or front ajax request.

Моя идея очень проста. Просто определите два разных имени для поля nonce. (Таким образом, кроме разработчика, никто не будет знать, какое имя для какой цели.) Пример:

add_action('wp_ajax_{my_ajax_hook}', 'my_ajax_function');
function my_ajax_function() {

    if( isset($_REQUEST['f_nonce']) ){
        $fromFront = true;
        $nonceField = 'f_nonce';
    }else{
        //by default from backend or you can alter;
        $fromFront = false;
        $nonceField = 'b_nonce';
    }

    if ( ! wp_verify_nonce( $_REQUEST[$nonceField], 'my-nonce-pass' ) ) {
        die( 'Security check' ); 

    } else {
        // Do stuff here according to the value of $fromFront;

    }
    exit();
}

Данные nonce должны быть при каждом вызове ajax для защиты вашего скрипта в соответствии с http://codex.wordpress.org/AJAX_in_Plugins .

 0
Author: Reza Mamun, 2013-12-27 06:23:57