How to remove _wp_http_referer from URL when using WP_List_table?

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.

Read More

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

Related posts

Leave a Reply

6 comments

  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;
    } 
    
  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
    }
    
  3. Give the following script in footer or any common js

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

  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.

  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.

  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);
        }
    }