AJAX endpoints being natively supported in WordPress is awesome. Not being able to separate a frontend request (coming from a theme/frontend plugin) from a backend request (coming from the admin panel) is not as awesome.
Here’s a function to determine if a request is coming from the frontend or backend. It uses the HTTP referer to determine which URL the incoming call to admin-ajax.php originated from. If it originated from a /wp-admin/ url, we know for sure that it was a backend request.
function request_is_frontend_ajax()
{
$script_filename = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
//Try to figure out if frontend AJAX request... If we are DOING_AJAX; let's look closer
if((defined('DOING_AJAX') && DOING_AJAX))
{
//From wp-includes/functions.php, wp_get_referer() function.
//Required to fix: https://core.trac.wordpress.org/ticket/25294
$ref = '';
if ( ! empty( $_REQUEST['_wp_http_referer'] ) )
$ref = wp_unslash( $_REQUEST['_wp_http_referer'] );
elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) )
$ref = wp_unslash( $_SERVER['HTTP_REFERER'] );
//If referer does not contain admin URL and we are using the admin-ajax.php endpoint, this is likely a frontend AJAX request
if(((strpos($ref, admin_url()) === false) && (basename($script_filename) === 'admin-ajax.php')))
return true;
}
//If no checks triggered, we end up here - not an AJAX request.
return false;
}
Usage
if(request_is_frontend_ajax()) {
//Do something only on frontend ajax
}