How to remove _wp_http_referer from URL when using WP_List_table?

The question:

I have built a plugin that displays a table using the WP_List_Table class.
The table displays entries on which it’s possible to apply a filter and some bulk actions.

The problem is that when I click on the “filter” button or “apply bulk action” button multiple times, the _wp_http_referer paramater is added to the URL and keeps being longer and longer each time I click on the button.

Eventually the URL is so long that I get a blank page in the browser with the following error message:

Request-URI Too Large
The requested URL's length exceeds the capacity limit for this server.

I think I have set up the filter and bulk action select menus properly inside a simple form tag:

form action method="get"

The same problem seems to have been described here:
How to stop _wpnonce and _wp_http_referer from appearing in URL. I am facing the same issue and wondering if someone would have any idea how to remove the _wp_http_referer paramater from the URL after clicking on my form action buttons.

Thanks

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

As the last commenter on that Q suggested, you should probably check for actions, remove the query args and redirect. Something like:

$doaction = $wp_list_table->current_action();
if ( $doaction && isset( $_REQUEST['SOMEVAR'] ) ) {
    // do stuff
} elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
    wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
    exit;
} 

Method 2

Let me help you! Overwrite the parent method display_tablenav of WP_List_Table class removing the wp_nonce_field execution.

/**
 * Generates the table navigation above or bellow the table and removes the
 * _wp_http_referrer and _wpnonce because it generates a error about URL too large
 * 
 * @param string $which 
 * @return void
 */
function display_tablenav( $which ) 
{
    ?>
    <div class="tablenav <?php echo esc_attr( $which ); ?>">

        <div class="alignleft actions">
            <?php $this->bulk_actions(); ?>
        </div>
        <?php
        $this->extra_tablenav( $which );
        $this->pagination( $which );
        ?>
        <br class="clear" />
    </div>
    <?php
}

Method 3

Give the following script in footer or any common js

setTimeout(function() {
jQuery( “input[name*=’_wp_http_referer’]” ).remove();
}, 500);

Method 4

The accepted answer is the best way to do it, but if the List Table appears on a custom admin page, you’re going to run into headers already sent errors.

The best I can come up with is to detect a nested _wp_http_referer on admin_init and do the redirect there.

add_action( 'admin_init', 'wpse_80112' );

function wpse_80112() {

    // If we're on an admin page with the referer passed in the QS, prevent it nesting and becoming too long.
    global $pagenow;

        if( 'admin.php' === $pagenow && isset( $_GET['_wp_http_referer'] ) && preg_match( '/_wp_http_referer/', $_GET['_wp_http_referer'] ) ) :
            wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
            exit;
        endif;

}

Be aware of the timing of your code. If you handle the list table actions after this hook (e.g. within your list table class), then there is a risk of redirect before the action is executed – and therefore will be ignored and need a second request. Be sure to handle this in your own implementation as and how appropriate.

You may consider using the load-{page-hook} action to handle actions, where {page-hook} is the return from your add_submenu_page (or similar) call.

Method 5

I know this is an old question but i setteled for a modified version of Sijo Thomas Maprayil’s awnser

jQuery("input[name='_wp_http_referer'], input[name='_wpnonce']").remove();

No need for a timeout as long as the script is executed below the search box.

I wonder why these fields even get added if wordpress does a redirect to get rid of them again. Very sub optimal to say the least.

Method 6

Here is the code that does the trick:

public function strip_wp_http_referrer () {
    $current_url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

    if (strpos($current_url, '_wp_http_referer') !== false) {
        $new_url = remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes($current_url));
        wp_redirect ($new_url);
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment