Prevent generation of browser history on `POST` to self

310 Views Asked by At

I have a server that, when POST is sent to /generate, it generates "stuff" in an HTML page. The page itself uses JavaScript window.history.replaceState(null, null, window.location.href) so that the user can reload the page (using GET) and see the same data without the browser asking if it should resend POST information.

The page also has a "Regenerate" button that sends POST back to /generate to regenerate new information. Unfortunately this results in a new point in navigation history, so that the user can hit the browser "Back" button to go back to the previous version of the /generate page. I don't want this behavior. I want the page to be able to "replace" the current page with the new generated contents without creating a new point in navigation history.

(I am well aware that a more modern approach would be to asynchronously query the server using Ajax and update the page dynamically. I imagine that is what will be done in an upcoming release. I'm asking for a quick workaround for the current release of this product.)

Is there a way that I can have a page send a POST so that it doesn't result in a new point in navigation history? The JavaScript on the page can detect if regeneration occurred, but I can't find out how to remove the current navigation state, only replace it. Ideally I would like to POST without creating a new point in navigation history at all.

I don't see any way this is possible, but I thought I would run it by the community to see if someone knew a trick.

2

There are 2 best solutions below

0
Mel On

Like you have mentioned, it is indeed not possible to prevent generation of browser history. A POST request on the same page will still create a URL, you can only code your way to mask the method or make it look like it's in the same state.

I find the conversations in these two community posts relevant for this matter:

2
Hind Sagar Biswas On

Preface

It's not possible to send a POST request without creating a new point in the navigation history. When you perform a POST request, the browser considers it a new interaction with the server and therefore adds a new entry to the history.

But similar behavior can be achieved without adding to the navigation history.

Solution

Approach

  1. Attach an event listener to your "Regenerate" button.
  2. When the button is clicked, use JavaScript to send a POST request to the server using the Fetch API or an XMLHttpRequest. This allows you to send the data to the server without triggering a page reload.
  3. Handle the response from the server and update the page content with the new data.
  4. Use the window.history.replaceState method to update the URL if necessary.

Simplified Example

document.getElementById('regenerateButton').addEventListener('click', function() {
    // Perform an asynchronous POST request
    fetch('/generate', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json', // Adjust the content type as needed
        },
        body: JSON.stringify({ /* Your POST data here */ }),
    })
    .then(response => response.text()) // Assuming the response is text, adjust as needed
    .then(newData => {
        // Update the page content with the new data
        document.getElementById('contentContainer').innerHTML = newData;

        // Optionally, update the URL without adding to the history
        window.history.replaceState(null, null, window.location.href);
    })
    .catch(error => {
        console.error('Error:', error);
    });
});

NOTE: I did this hurriedly, so there might be some typo or mistakes.