0

I started to work with ajax some time ago, but I'm getting a strange problem that I don't have any idea of the reason.

I work with 3 files to make all my pages: a header, a footer and the content files. In header I put my ajax code that is something like this:

        $(document).on("click", '.ajax a', function (e) {
           e.preventDefault();
           var href = $(this).attr("href");
           if (href == location.pathname) return; // Prevent from refresh on click the current page link
           loadContent(href); // Make the AJAX call
           window.history.pushState('', '', href); // Changes the link
        });

        //MAKE BACK/FORWARD WORKS
        window.onpopstate = function(event) {
           loadContent(location.pathname);
        };

  ///////////////////////////////////////AJAX ITSELF
  function loadContent(url){
     $.ajax({
        url:url,
        type:'GET',
        error: function(){
           alert("Oops, something went wrong :(");
        },
        success:
        function(data){
           $('#content').html(data); // Inject page into the content div
           document.title = $("#titulosads").val(); // Changes the page title
        }
     });

  }

After that I open the #content div that will be closed in footer.

And in each page file, I use these codes for include the header.php and the footer.php when is needed:

function includeheader($pagename, $pagedescription)
{
    $title = $pagename;
    $description = $pagedescription;
    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        echo "<input type='hidden' id='titulosads' value='".$title."' />";
    } else {
        include 'header.php';
    }
}

And for the footer:

function includefooter()
{
    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    } else {
        include 'footer.php';
    }
}

So, basically, this is my pages:

<?php
include_once 'includes/checkajax.php';
includeheader('Contact');
?>

Content of the page here!

<?php
includefooter();
?>

Well, this is my issue: it gets a little strange when I use the GET method of AJAX.

Things get duplicated when you click in other link and back on the first. You can check it on http://feely.com.br

When I change the method to POST or when I activate chrome dev tools that disable the cache, everything works fine.

Oh, there is a lot of errors on console that I don't have idea about what they mean.

A picture of the errors:

Duplicated content

Help :(

Igor
  • 131
  • 3
  • 10
  • Well, if you yourself already found out that this is a caching issue, then follow that hint. First take care that you mark your requests to _not_ getting cached by the browser by means of http headers you add. Second take care to use a unique URL for the requests, that is typically done by simply adding a microtime based request argument to the URL. – arkascha May 15 '16 at 06:43
  • So, if I disable the cache, the problem is solved. I didn't get what did you mean by "use a unique url". The same for "add a microtime based request argument to the URL". =( – Igor May 15 '16 at 06:52
  • It is a "poor mans trick" to prevent caching of request payloads, if you don't have proper caching preventing http headers in place. Simply add a unique parameter to the request URL. So instead of `https ://some-server/resource` use `https ://some-server/resource?23459120998345`, where is number is something unique, typically a micro time based value. You can safely ignore that parameter on the server side. It simply makes the URL unique which means the browser certainly will _not_ load a payload from its cache, since the URL is "new". However proper caching headers are the preferred solution. – arkascha May 15 '16 at 06:55
  • If I'm going to "disable" the cache, wouldn't it be better (or simplier) if I use the POST method? And, as you said, a proper caching headers would be the preferred. How would I do it? – Igor May 15 '16 at 07:05
  • The difference between the http verbs `GET` and `POST` have nothing to do with caching. Those are strictly separate things. The two verbs serve different types of actions. `GET` fetches some resource whilst `POST` uploads some resource. Both receive a response that can be cached or not. Preventing responses to be cached by a client is done, as already written above, by using correct http headers. Check the accepted answer to that question: http://stackoverflow.com/questions/13640109/how-to-prevent-browser-cache-for-php-site – arkascha May 15 '16 at 07:08
  • As you can be read here http://www.w3schools.com/jquery/jquery_ajax_get_post.asp "However, the POST method NEVER caches data..." There is a way to prevent caching of the first page? I feel that there is a better solution than disable the cache. – Igor May 15 '16 at 07:25
  • You should not rely on the `w3schools` page. It is well known for its vague and questionable statements. There is a reason why they are dubbed "w3fools". I cannot see any standard definition of the http methods that makes a statement about POST replies getting cached or not. I'd say that is up to the specific browser and its implementation. About "caching of the first page": sure there is a way. I explained it twice above. The correct way is to use http headers. That is what they are for, to tell the browser how to handle the actual response payload. – arkascha May 15 '16 at 07:31
  • Well, you're right. Solved. I'm fool hahahaha, sorry. I added the lines in the accepted answer of the question you sent me. Thank you :) Could you add it as an answer? – Igor May 15 '16 at 07:41
  • Sure, did that. Great that you could solve your issue :-) – arkascha May 15 '16 at 07:44

2 Answers2

2

Well, if you yourself already found out that this is a caching issue, then follow that hint:

Either take care that you mark your requests to not getting cached by the browser by means of http headers you add, or use a unique URL for the requests, that is typically done by simply adding a micro time based request argument to the URL. The preferred method however is to use http headers to tell the browser how to handle a response payload. That is what http headers are for...

PHP offers the header() function for that:

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
arkascha
  • 41,620
  • 7
  • 58
  • 90
0

I think you was loading a whole pagecontent inside a part of a similar page. So, instead of paste the content in div#content you have to paste it over the whole page. Give it a try.

  • 1
    Like, load the files over the whole page? If I load the header and the footer again, what would be the advantage of using ajax? – Igor May 15 '16 at 06:51
  • I had made a similar website, which was reloading everything. Maybe your case you have to make one page with includes header and footer. All other pages contains only the text (no PHP). When loading that page inside div#content you are maybe not loading the header inside your content. – Ben van Hartingsveldt 'Y' May 15 '16 at 07:14
  • What if the users access the links directly? Like, supposing that he access About page, the link will change to "http://feely.com.br/about" What if the `about.php` file doesn't have header and footer? – Igor May 15 '16 at 07:27
  • Then you do this: with ajax you are sending the _withAJAX=1 parameter and on the other page you will not include header/footer when _withAJAX is 1. Because nobody will request feely.com.br/about with that parameter exept AJAX. – Ben van Hartingsveldt 'Y' May 15 '16 at 07:35
  • It wouldn't change the problem. It is about caching of the header. But thank you, Ben =) I fixed it with arkascha comment. – Igor May 15 '16 at 07:42