I've got a site which uses jQuery and Ajax to change the site content without reloading the page. The site contains content which I often change. But somehow the page gets saved in the cache so it doesnt show the changes.
I tried several things to make the browser not to save the site into the cache like METAs and PHP. But it doesnt work.
I think it has to do with the fact, that the page always has the same URL so I thought about adding a random number to it like:
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
(It's not my code, found it with some googlin) But this only adds the link ID I clicked on to the URL. I don't know where to put "Math.random()" to add a random number.
Hope you can help!
Just use cache : false. jQuery will automatically add a timestamp to the end of the URL for you, making sure that ajax requests are never cached.
Quoting the the API reference for .ajax()
cache
Default: true, false for dataType 'script' and 'jsonp'
If set to false, it will force requested pages not to be cached by the browser. Setting cache to false also appends a query string parameter, "_=[TIMESTAMP]", to the URL.
Examples
Globally disable caching for all future ajax requests. See .ajaxSetup()
$.ajaxSetup({
cache: false
});
Disable caching per request. See .ajax()
$.ajax({
url: "test.html",
cache: false,
success: function(html){
$("#results").append(html);
}
});
If you are using jQuery's AJAX functions, try setting $.ajaxSetup( { cache: false } ) at the top of your page, and let jQuery take care of it for you.
Like most mentionned, you should use the jQuery cache parameter, but for your information, it is often done not using Math.random but with new Date().valueOf(), which is a time value pretty much guaranteed to be unique.
window.location.hash = $(this).attr('href')
.substr(0,$(this).attr('href').length-5)
+ Math.random();
Best option is to use timestamp with the request:
window.location.hash = $(this).attr('href')
.substr(0,$(this).attr('href').length-5)
+ timestamp;
Related
I'm running into a strange problem on my webpage using the jQuery $.get function. The code below is executed on page load:
$.get(urls.validateSession, function(data){
console.log(data);
});
I would expect this to make a GET request to urls.validateSession each time the page is loaded, then log the response data to the console.
It does this on the initial page load with no problems. But on subsequent page loads, jQuery does not make a new request to urls.validateSession. It instead just prints the exact same response data from the previous request (identical response timestamp and everything!)
Interestingly, when reloading the page with Shift + F5, jQuery does make a new request to urls.validateSession and I can see a new response timestamp.
Can anyone explain this behavior?
I think this previous question might help get you the desired result.
The JQuery get() method's cache is, by default set to true.
cache (default: true, false for dataType 'script' and 'jsonp')
And it sounds like your results are getting cached, that's why it doesn't bother to run the function each page load.
You can check out more ajaxSettings here
The snippet from #KevinB in the linked question:
$.get({
url: url,
cache: false
}).then(function(rdata){
console.log(rdata);
});
If you do not want caching on any of your AJAX requests, you could also set this field in your initial AJAX setup before running any AJAX functions.
$.ajaxSetup({
cache: false
});
To disable caching files from ajax requests, you can use jQuery's
$.ajaxSetup({
cache: false
});
But how does jQuery do this? I know jQuery is a javascript library, so whatever can be done with jQuery can be done with plain javascript. So my question is: What is the javascript code that jQuery uses under the hood to turn off ajax file caching?
This is the source of the cache
if ( s.cache === false ) {
s.url = rts.test( cacheURL ) ?
// If there is already a '_' parameter, set its value
cacheURL.replace( rts, "$1_=" + nonce++ ) :
// Otherwise add one to the end
cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
}
s is ajax's option,
If you set cache false, It will add a search to you request url,
The 'nonce' is jQuery.now(), It's a time;
So browser will not user cache when you send ajax , request url always differenrt.
I think that Today's Browsers use onunload = function(){} just like that (yes, exactly) to prevent the Browser from caching a web page, as it was when you left it to go to another page.
It's important to under stand, however, that that is not the same as the Browser's ability to remember the JavaScript loaded from your <script type='text/javascript' src='somePage.js'></script> tags when they have that src attribute. If you change your JavaScript on a live site, you'll want to change the name of that file, or, if the Client has not cleared their cache their Browser will attempt to load the file as it remembers it.
The easiest way to shut off browser caching of Ajax requests is with a query string parameter based on time.
var t = new Date().getTime();
console.log('some-url?_='+t);
This yields the following query string
?_=1481683928873
The browser will see this as a different request (assuming it only makes one per microsecond) and it will request the content from the server, rather then serving it from its cache.
If you read the docs they say:
cache (default: true, false for dataType 'script' and 'jsonp')
Type: Boolean
If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.
I'm using this plugin: https://github.com/padolsey/jquery.fn/tree/master/cross-domain-ajax/
And this is my code:
$.ajax({
dataType: 'html',
type: 'GET',
url: 'http://www.google.com',
crossDomain: true
}).done(function(data) {
$("#box").html('').append(data);
});
From my understanding, even though I have dataType: 'html' I'm fairly sure this is still getting me a response in JSONP.
I want to be able to grab the entire html of the page, everything I need to display the page in full. Comparable to an iframe. The reason I need to do this through ajax is because eventually I am going to need to pass parameters to the URL I am using. What is the best way to return a page's content in full HTML, so that I may display the page? Do I need to do anything to return the pages scripts/stylesheets as well?
Basically, the URL that I am calling needs to be returned so that I can append the return to a div id, and that div id should then look exactly like the page I was calling, as if I were to load that page independently in a browser window.
Thanks!
You can try Ajax-cross-origin a jQuery plugin.
http://www.ajax-cross-origin.com/
$.ajax({
crossOrigin: true,
url: url,
success: function(data) {
console.log(data);
}
});
Plugin referenced uses Yahoo YQL service as a proxy to get remote page. YQL will return json and you should be able to access your data in data.responseText. This is per limted docs for plugin
To be sure you can log the data to console and see it's structure.
Could do same thing without plugin by using YQL console to create URL needed to meet your scraping needs using their XPATH syntax
site.com/api/index.php is where I need the ajax request to go. From site.com/sub/ the request works perfectly but sub.site.com is sending the request to sub.site.com/api/index.php which obviously does not exist... I've Google and StackOverflowed the hell out of the question, but can't seem to find an answer that works.
Code:
var jQuery_ajax = {
url: "site.com/api/index.php",
type: "POST",
data: $.param(urlData),
dataType: "json"
}
var request = $.ajax(jQuery_ajax);
The most common answer was to set document.domain to the regular site, but that does not seem to do anything... I've also seen answers talking about iFrames, but I want to stay away from iFrames at all costs.
document.domain = "site.com";
** Note: everything is on the same server.
HACKY SOLUTION: made sub.site.com/api/index.php a file that simply reads
include_once("$path2site/api/index.php");
Once you've corrected the URL to http://site.com/api/index.php try adding the following to api/index.php:
header("Access-Control-Allow-Origin: http://sub.site.com");
e: it's possible that doing so may disallow use from site.com as well; I'm not seeing a way to provide two values, so you may need a way to tell it which site to use, like a ?sub=1 arg to index.php
I'm using jquery's ajax functions to grab a page fragment and display in a section of a page - this fragment includes html and references to external js files.
The program flow looks like this:
Main Page calls -> Fragment page which calls -> various large js files via script tags.
I've turned on the cache option on my initial ajax call so that the fragement page gets cached (no unique IDs appended to the url), however when the fragment is loaded, it appears that jquery rewrites the script urls to include a unix timestamp so that the browser downloads a new copy of the scripts every time. The scripts i'm calling are around 250kb minified and it's really hurting the user experience as the browser locks up whenever they're called. Is this a desired behaviour of jquery? Is there a way to disable the url rewrites?
Many many thanks for your help
This solution is less of a hack than Murdoch's solution:
$.ajaxPrefilter('script', function(options) {
options.cache = true;
});
See http://api.jquery.com/jQuery.ajaxPrefilter/
Looks like jQuerys's evalScript function is messing you up...
Line 543 of jQuery:
function evalScript( i, elem ) {
if ( elem.src )
jQuery.ajax({
url: elem.src,
async: false,
dataType: "script"
});
else
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
if ( elem.parentNode )
elem.parentNode.removeChild( elem );
}
Here is the breakdown of what happens:
The Main Page's JS calls:
$.ajax({
url:"frag.htm",
type:"GET",
success:callBackFunction
})
and GETs frag.htm which contains something like this:
<html><head><script src="test.js"></script></head><body>Content</body></html>
then your callback function is called which probably looks like this:
function callBackFunction(data){
$("#ajaxContent").html(data); // <- this is the beginning of your problems...
}
When jQuery's html(data) function is called is "cleans" the HTML by removing any script tags and then calls evalScript on each one.
evalScript, as you can see, doesn't specify "cache:true" so when it goes through $.ajax cache is null. When cache is null and the dataType is "script" jQuery sets cache=false.
So, to circumvent this problem try this:
function callBackFunction(data){
var tempAJAX = $.ajax; // save the original $.ajax
$.ajax=function(s){ // wrap the old $.ajax so set cache to true...
s.cache=true;
tempAJAX(s); // call old $.ajax
}
$("#ajaxContent").html(data); // insert the HTML and download the <script>s
$.ajax = tempAJAX; // reset $.ajax to the original.
}
}
Before we insert the new HTML from "frag.htm" into the Main Page we intercept all calls to $.ajax, modify the object to include cache=true, and then after the script is loaded insert the HTML.
Let me know if you have any questions.
Force the webserver to serve the script with a expire date in the future.
If you use dataType = "script" as an option for jquery ajax the caching will be disabled by default, see http://docs.jquery.com/Ajax/jQuery.ajax#options, try set it manually to "html".
$.ajax({
type: "GET",
url: "test.js",
dataType: "html" // if not set jquery will guess what type it is and disables caching when matching "script"
});