Search code examples
jqueryajaxbrowser-historypushstate

Changing page URL with pushstate preventing ajax from working


I'm trying to fake the page url whilst using ajax to also change the page content. I'm also using jquery transitions in combination with this ajax, but when I add the pushstate to change the URL, it stops the ajax from changing the page content.

If I comment out the line // window.history.pushState(null, "null", href) then the transitions work fine, but the url is then not changed. Can anyone see what I'm doing wrong?

$("#contactRoll").on("click", function(event) {
    
    event.preventDefault();

    $(document).attr("title", "Contact Page");

    //get the 'fake' link
    const href = $(this).attr("href")

    //fake the url
    window.history.pushState(null, "null", href)

    $('.main-logo').fadeOut(500)
    $('.main-logo-reverse').delay(500).fadeIn(300)

    $.ajax({
      //set the fake url
      url: href,
      success: function (data) {

        $("header").animate({marginTop: "100vh"}, function () {
          const newPage = $(data).filter("#main").html()
          
          $("#main").html(newPage)
          $("section#contact").animate({marginTop: "0vh"})
         
        })
      }
    })
})

Solution

  • https://developer.mozilla.org/en-US/docs/Web/API/History_API

    Using history.pushState() changes the referrer that gets used in the HTTP header for XMLHttpRequest objects created after you change the state. The referrer will be the URL of the document whose window is this at the time of creation of the XMLHttpRequest object.

    Try adding the

    //fake the url
    window.history.pushState(null, "null", href)
    

    to the success: function(data) { ... } callback so the url state is changed after the Ajax request is completed.

    $.ajax({
        url: href,
        success: function (data) {
    
            //fake the url
            window.history.pushState(null, "null", href)
            $("header").animate({marginTop: "100vh"}, function () {
            const newPage = $(data).filter("#main").html()
    
            $("#main").html(newPage)
            $("section#contact").animate({marginTop: "0vh"})
    
          })
        }
      })