Ok I played around a bit and have something that might work. ideally you’d just ecxlude the file. It is, as you’ve experienced, typically necessary for the front-end to function. However, with some code you might be able to avoid the issue. To summarize, we will:
1. Filter the admin_url()
function so that any use of the function like admin_url( 'admin-ajax.php' )
will change the URL to a custom URL.
2. Create a custom URL, https://website.com/ajax/, that we will use to replace the admin-ajax.php URL.
3. Set it up so that requests to /ajax
load the admin-ajax.php
file.
The problem you might have is that if a plugin is not using admin_url( 'admin-ajax.php' )
to create the AJAX URL, but doing something like admin_url() . 'admin-ajax.php'
instead, then this won’t work for those plugins.
So the code for #1 is:
function asifriazkhan_ajax_url( $url, $path ) {
if ( strpos( $path, 'admin-ajax.php' ) !== 0 ) {
$url = site_url( '/ajax/' );
}
return $url;
}
add_filter( 'admin_url', 'asifriazkhan_ajax_url', 10, 2 );
So now, any use of admin_url( 'admin-ajax.php' )
in a plugin will return https://website.com/ajax/
.
The next piece is these two functions:
function asifriazkhan_ajax_rewrite_rule() {
add_rewrite_rule( 'ajax/?$', 'index.php?asifriazkhan_ajax=1', 'top' );
}
add_action( 'init', 'asifriazkhan_ajax_rewrite_rule' );
function asifriazkhan_ajax_query_vars( $query_vars ) {
$query_vars[] = 'asifriazkhan_ajax';
return $query_vars;
}
add_filter( 'query_vars', 'asifriazkhan_ajax_query_vars' );
With these bits of code https://website.com/ajax/
is now a valid URL, and will give us a custom query variable, asifriazkhan_ajax
, which we can use to insert the AJAX functionality.
So then the last bit of code is to check if the request is for https://website.com/ajax/
using our custom query variable. If it is, we will include admin-ajax.php so that it can handle the request:
function asifriazkhan_ajax_include() {
global $wp_query;
if ( $wp_query->get( 'asifriazkhan_ajax' ) === '1' ) {
include ABSPATH . '/wp-admin/admin-ajax.php';
exit;
}
}
add_action( 'template_redirect', 'asifriazkhan_ajax_include' );
Now most, if not all, AJAX requests by plugins should be sent to – and handled by – https://website.com/ajax/
, avoiding direct requests to admin-ajax.php, which should solve your problem.
I’ve tested the code and it works, including for core WordPress AJAX functionality, but it depends on 3rd-party plugins doing their AJAX a certain way.