2

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

4

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;
} 
  • +1. This is almost an exact copy of code from WP Core. See wp-admin/edit.php. – Mark Aug 25 '17 at 15:49
1

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
}
1

Give the following script in footer or any common js

setTimeout(function() { jQuery( "input[name*='_wp_http_referer']" ).remove(); }, 500);
1

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.

0

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

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 te get rid of them again. Very sub optimal to say the least.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.