Search code examples
javascriptajaxfetchpushstatehtml5-history

Is there a particular behavior with fetch and pushState?


I am having an issue trying to fetch some datas using pushState.

So i basically have 4 functions:

  • an event listener on click
  • a function to grab the link needed
  • a function to trigger an animation
  • and a function to fetch this url

Everything works fine until i try to push a state in the history.

history.pushState before, or after my fetch request, breaks the request like so: controller/controller/about.php for some reason.

I tried a console.log(url); on all 4 functions and the result is the same (a good url to fetch: controller/about.php for example)

I tried history.pushState inside my fetch request and it works fine (loads controller/about.php for example) but i need to work with the popstate event and call the same fetch function again.

My summarized code:

const loadNewContent = async url => {
    const response = await fetch(url, { headers: headers });
    // Tried adding pushState inside fetch request
    // window.history.pushState(url, `${url}`, url);
};

// function that fires animations then load the last function
const changePage = url => {
    loadNewContent(url).catch(error => console.error(error));;
};

const ajax = e => {
    // Tried adding pushState before fetch fires
    // window.history.pushState(newPage, ``, newPage);
    changePage(newPage);
    // Tried adding pushState after fetch fires
    // window.history.pushState(newPage, ``, newPage);
};

// Click event fires ajax function
ajax(e);

Solution

  • This is just how relative paths work. Everything after the last / is discarded, and the relative URL is appended.

    http://localhost/imparfait + controller/about.php becomes http://localhost/controller/about.php

    while

    http://localhost/imparfait/controller/article.php + controller/about.php becomes http://localhost/controller/controller/about.php

    Use an absolute path (starting with /), a scheme-relative URL (starting with //localhost), an absolute URL (starting with http://), or construct a URL using the URL object which would let you specify the base instead of fetch getting it from location.href.