Trouble with AJAX page loading and history.pushState functionality following navigation away from the site

My website utilizes XMLHttpRequests to fetch specific parts of webpages upon a user clicking a link.

Below is the relevant code snippet:

function requestPage(url, push) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            main.innerHTML = xhr.responseText;
            attachLinkClickHandlers(main); // `main` = container element

            if (push)
                window.history.pushState(url, title, url);
        }
    };

    xhr.open('GET', url);
    xhr.setRequestHeader('Content-Only', 1); 
    xhr.send();
}

window.addEventListener('popstate', function (e) {
    var page = e.state;
    requestPage(page, false);
});

window.history.replaceState(location.href, document.title, location.href);
attachLinkClickHandlers(document);

When a link is clicked:

requestPage(link.href, true);

Here are examples of server responses:

Response from normal request:

<!doctype html>
<html>
    <head>
        ...stuff...
    </head>
    <body>
        <main>
            <h1>Content</h1>
            <p>Content Content</p>
        </main>
    </body>
</html>

Response when Content-Only header is set:

<h1>Content</h1>
<p>Content Content</p>

Everything seems to be working correctly, except when I click on an external link and then try to navigate back using the browser's back button. At that point, only the content without the usual HTML, head, or body tags is displayed as per XHR response, meaning CSS and JavaScript are also missing.

I'm looking for suggestions on how to ensure the browser loads the complete page in such scenarios.

Answer №1

Are you fetching different types of content using the same URL?

I faced a similar issue where I was retrieving either an HTML application page or JSON data by sending different request headers to the same URL. When navigating away and then clicking back, the browser would display the JSON response because it was the last cached response associated with that URL.

It seems that the browser only keeps track of URLs and their responses, not the specific type of content requested. Therefore, after navigating away and returning, the browser only has the URL (and potentially a cached response).

To solve this problem, I changed the URLs used to fetch the JSON data separate from those used to manipulate the browser history.

// on click of product item 123
var url = 'http://<webserver>/products/123',
    title = 'Product 123';

history.pushState({
        url: url,
        title: title
    }, title, url);

product = $.getJSON(url + '?json=1'); // make the url different

I created some tests to demonstrate how this solution works https://github.com/robbishop/history-api-test

I tested this in multiple browsers and observed differences between Firefox (version 50.0) and Chrome. For example, in Chrome, if you modify the page content and call history.pushState with a fake URL, then navigate away and click back, you will see a 404 error page. However, in Firefox, it actually restores the page as you last viewed it. Therefore, it is important to associate URLs with a single content type when manipulating browser history directly to ensure consistent behavior across browsers.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The `required` attribute is ineffective when used with the `<form>` element

My required attribute isn't enforcing mandatory field completion before form submission. HTML Code: <!-- Modal Content --> <form class="modal-content2"> <div class="container3"> < ...

How can I change the background color of my notification box to red if the count is not equal to zero?

When the count equals 0, I don't want any effect on the notification box. However, when the count is not equal to zero, I want the notification box to turn red. I tried implementing this, but it's not working as expected. By not working, I mean n ...

How to make a checkbox function as a radio button within a container div

Is there a way in my code to select only one checkbox from each .form-group.row, similar to how radio buttons work? Each form-group may appear multiple times with checkboxes having the same name. I have been trying to implement a selection mechanism within ...

What is the best way to cut strings in JavaScript or jQuery?

Can anyone provide guidance on how to trim using this code? $('#type_of_station').text() Here is the result: >>> $('#type_of_station').text() "pizza delivery system " It appears that there is a space after the last word in ...

AngularJS binding variables to HTML tag attributes

Currently, I am going through the tutorials and documentation for Angularjs that is provided on the official Angularjs website. One of the examples involves adding a select box for ordering which looks like this: <select ng-model="orderProp"> ...

Updating Rails record using Ajax with select_tag and onchange functionality

I'm working on an index view where I want to update a table data dynamically using select_tag onchange feature without the need to refresh the page. Do I need to use Coffeescript to detect the onchange event, capture the new value, and then send it to ...

Resolving the dropdown issue in jQuery and ASP.NET

In my ASP.NET page, I have a drop-down list that triggers an ASP.NET AJAX request whenever its value changes. Additionally, I have attached a jQuery "change" event handler to the drop-down to run certain code when the value changes. This setup seems to be ...

Minimum requirement for browsers such as IE9 and other compatible versions

My web app requires IE9 - what are the equivalent browser versions for Firefox, Chrome, Opera, and others? I am able to detect the user's current browser and version, and if it is not compatible, I am considering providing links for them to download ...

What is the best way to populate missing days in an array up to the current date that do not already contain the "Present" element?

Consider the array below which contains attendance data for an employee (Retrieved from Mongo using Ajax): [{"_id":"5fcdcd49c3657d1e05b846f5","title":"Present","allDay":true,"start":"2020-11- ...

What could be the reason for my error messages not displaying when I have defined them on a static method in the schema, despite the error handling seeming to

I have created a static method in my schema that defines the User document structure in my MongoDB database. This method, .findByCredentials(), is used to verify if a user-provided email and password match an existing user and hashed password in the databa ...

What could be causing npm to not recognize my module in the "require" statement?

Currently, I am in the process of developing an npm module and conducting tests before making it available to the public. The method I am following is outlined in a blog post found at this link. However, I am encountering difficulties when trying to requir ...

"Troubleshooting: Problems with Triggering Dynamic Image Button Event Handlers

Building a dynamic table on page load, I placed it inside an update panel to enable adding rows dynamically without a full page postback. Each row consists of 4 cells - the first 3 containing textboxes and the 4th cell containing an image button for row de ...

struggling with the predictive text feature, need some assistance

Currently, I am utilizing the material-table library and I have made the decision to incorporate a feature similar to Google's "typeahead" functionality. Here is an example of what I am trying to achieve: https://i.sstatic.net/r6jCd.png In order to ...

Sometimes jQuery may require multiple executions with just one click

Content of index.php <script type="text/javascript" src="//<?php echo $_SERVER["SERVER_NAME"];?>/javascript/jquery-1.10.2.min.js" ></script> <script type="text/javascript"> $(document).ready(function() { $( document ).on( 'c ...

Implementing a JQuery modal with backend coding

I have encountered a problem in my ASP.NET code-behind where I am trying to incorporate a modal popup. Despite my efforts, I have not been able to successfully implement it. Do you have any suggestions on how I should proceed with this process? <scrip ...

Monitoring Selection Updates on Firefox for Android using JavaScript

I am in search of a method to monitor text selections on a webpage. I require code to run every time there is a change in selection. While I have successfully achieved this on the main desktop browsers, I am facing difficulties with Firefox for Android. I ...

Verifying if a dropdown option has been chosen through validation in JavaScript

Currently, I am working on implementing a validation block in my JavaScript code to ensure that users have selected a value before proceeding. If a value is not selected, I want to display a pop-up message prompting them to do so. function validate(form) ...

The php script fails to return any response to Ajax

Why is my code not working with jQuery alert and Firefox response? The database query returns successful records, so what am I missing? Jquery ajax. $.ajax({ type : "POST", url : "include/add_edit_del.php?model=teksten_display ...

The image fails to display on the webpage: nodejs (handlebars)

Trying to display an image on a page, the address is correct, but when clicking on the image icon it shows "Cannot GET /images/1640388048496.jpg". I am using nodejs, express, handlebars and the name of the image is stored in MongoDB. The server is running ...

Children can easily access multiple items within a list by using the ul tag

I am struggling with changing the class of ul inside the ul.navigator. I want to change it only when I click on a particular li, but my current approach doesn't seem to be working. Can anyone provide some guidance or assistance? $('.navigator& ...