Jquery not appending timestamp for cache - javascript

I want to send an ajax request using sortable from jquery-ui. When I re-sort a list, for some reason, the ajax call isn't appending timestamp onto the querystring to avoid caching. Why won't this code work?
$('#categorylist').sortable({
placeholder: "ui-state-highlight",
update:function(e, ui){
var categorylist = $('#categorylist').sortable('serialize', {attribute:'data-id'});
$.ajax({
url:'actions_category.php?action=rank',
method:'post',
data:categorylist,
cache:false
});
}
});

It will only append the time stamp for GET and HEAD requests. It should not be needed for other types of requests except in IE8 for POST requests where you have already issued a GET request against the URL.
http://api.jquery.com/jQuery.ajax/

Note the supported HTTP Methods
http://api.jquery.com/jQuery.ajax/
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.

Related

express.js res.header doesn't work after ajax call [duplicate]

So I've got this jQuery AJAX call, and the response comes from the server in the form of a 302 redirect. I'd like to take this redirect and load it in an iframe, but when I try to view the header info with a javascript alert, it comes up null, even though firebug sees it correctly.
Here's the code, if it'll help:
$j.ajax({
type: 'POST',
url:'url.do',
data: formData,
complete: function(resp){
alert(resp.getAllResponseHeaders());
}
});
I don't really have access to the server-side stuff in order to move the URL to the response body, which I know would be the easiest solution, so any help with the parsing of the header would be fantastic.
cballou's solution will work if you are using an old version of jquery. In newer versions you can also try:
$.ajax({
type: 'POST',
url:'url.do',
data: formData,
success: function(data, textStatus, request){
alert(request.getResponseHeader('some_header'));
},
error: function (request, textStatus, errorThrown) {
alert(request.getResponseHeader('some_header'));
}
});
According to docs the XMLHttpRequest object is available as of jQuery 1.4.
If this is a CORS request, you may see all headers in debug tools (such as Chrome->Inspect Element->Network), but the xHR object will only retrieve the header (via xhr.getResponseHeader('Header')) if such a header is a simple response header:
Content-Type
Last-modified
Content-Language
Cache-Control
Expires
Pragma
If it is not in this set, it must be present in the Access-Control-Expose-Headers header returned by the server.
About the case in question, if it is a CORS request, one will only be able to retrieve the Location header through the XMLHttpRequest object if, and only if, the header below is also present:
Access-Control-Expose-Headers: Location
If its not a CORS request, XMLHttpRequest will have no problem retrieving it.
var geturl;
geturl = $.ajax({
type: "GET",
url: 'http://....',
success: function () {
alert("done!"+ geturl.getAllResponseHeaders());
}
});
The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.
http://www.checkupdown.com/status/E302.html
The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser
Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.
How to manage a redirect request after a jQuery Ajax call
Catching 302 FOUND in JavaScript
HTTP redirect: 301 (permanent) vs. 302 (temporary)
The underlying XMLHttpRequest object used by jQuery will always silently follow redirects rather than return a 302 status code. Therefore, you can't use jQuery's AJAX request functionality to get the returned URL. Instead, you need to put all the data into a form and submit the form with the target attribute set to the value of the name attribute of the iframe:
$('#myIframe').attr('name', 'myIframe');
var form = $('<form method="POST" action="url.do"></form>').attr('target', 'myIframe');
$('<input type="hidden" />').attr({name: 'search', value: 'test'}).appendTo(form);
form.appendTo(document.body);
form.submit();
The server's url.do page will be loaded in the iframe, but when its 302 status arrives, the iframe will be redirected to the final destination.
UPDATE 2018 FOR JQUERY 3 AND LATER
I know this is an old question but none of the above solutions worked for me. Here is the solution that worked:
//I only created this function as I am making many ajax calls with different urls and appending the result to different divs
function makeAjaxCall(requestType, urlTo, resultAreaId){
var jqxhr = $.ajax({
type: requestType,
url: urlTo
});
//this section is executed when the server responds with no error
jqxhr.done(function(){
});
//this section is executed when the server responds with error
jqxhr.fail(function(){
})
//this section is always executed
jqxhr.always(function(){
console.log("getting header " + jqxhr.getResponseHeader('testHeader'));
});
}
try this:
type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
var headers = XMLHttpRequest.getAllResponseHeaders();
}
+1 to PleaseStand
and here is my other hack:
after searching and found that the "cross ajax request" could not get response headers from XHR object, I gave up. and use iframe instead.
1. <iframe style="display:none"></iframe>
2. $("iframe").attr("src", "http://the_url_you_want_to_access")
//this is my aim!!!
3. $("iframe").contents().find('#someID').html()

X-Forecast-API-Calls http response header inclusion and usage [duplicate]

So I've got this jQuery AJAX call, and the response comes from the server in the form of a 302 redirect. I'd like to take this redirect and load it in an iframe, but when I try to view the header info with a javascript alert, it comes up null, even though firebug sees it correctly.
Here's the code, if it'll help:
$j.ajax({
type: 'POST',
url:'url.do',
data: formData,
complete: function(resp){
alert(resp.getAllResponseHeaders());
}
});
I don't really have access to the server-side stuff in order to move the URL to the response body, which I know would be the easiest solution, so any help with the parsing of the header would be fantastic.
cballou's solution will work if you are using an old version of jquery. In newer versions you can also try:
$.ajax({
type: 'POST',
url:'url.do',
data: formData,
success: function(data, textStatus, request){
alert(request.getResponseHeader('some_header'));
},
error: function (request, textStatus, errorThrown) {
alert(request.getResponseHeader('some_header'));
}
});
According to docs the XMLHttpRequest object is available as of jQuery 1.4.
If this is a CORS request, you may see all headers in debug tools (such as Chrome->Inspect Element->Network), but the xHR object will only retrieve the header (via xhr.getResponseHeader('Header')) if such a header is a simple response header:
Content-Type
Last-modified
Content-Language
Cache-Control
Expires
Pragma
If it is not in this set, it must be present in the Access-Control-Expose-Headers header returned by the server.
About the case in question, if it is a CORS request, one will only be able to retrieve the Location header through the XMLHttpRequest object if, and only if, the header below is also present:
Access-Control-Expose-Headers: Location
If its not a CORS request, XMLHttpRequest will have no problem retrieving it.
var geturl;
geturl = $.ajax({
type: "GET",
url: 'http://....',
success: function () {
alert("done!"+ geturl.getAllResponseHeaders());
}
});
The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.
http://www.checkupdown.com/status/E302.html
The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser
Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.
How to manage a redirect request after a jQuery Ajax call
Catching 302 FOUND in JavaScript
HTTP redirect: 301 (permanent) vs. 302 (temporary)
The underlying XMLHttpRequest object used by jQuery will always silently follow redirects rather than return a 302 status code. Therefore, you can't use jQuery's AJAX request functionality to get the returned URL. Instead, you need to put all the data into a form and submit the form with the target attribute set to the value of the name attribute of the iframe:
$('#myIframe').attr('name', 'myIframe');
var form = $('<form method="POST" action="url.do"></form>').attr('target', 'myIframe');
$('<input type="hidden" />').attr({name: 'search', value: 'test'}).appendTo(form);
form.appendTo(document.body);
form.submit();
The server's url.do page will be loaded in the iframe, but when its 302 status arrives, the iframe will be redirected to the final destination.
UPDATE 2018 FOR JQUERY 3 AND LATER
I know this is an old question but none of the above solutions worked for me. Here is the solution that worked:
//I only created this function as I am making many ajax calls with different urls and appending the result to different divs
function makeAjaxCall(requestType, urlTo, resultAreaId){
var jqxhr = $.ajax({
type: requestType,
url: urlTo
});
//this section is executed when the server responds with no error
jqxhr.done(function(){
});
//this section is executed when the server responds with error
jqxhr.fail(function(){
})
//this section is always executed
jqxhr.always(function(){
console.log("getting header " + jqxhr.getResponseHeader('testHeader'));
});
}
try this:
type: "GET",
async: false,
complete: function (XMLHttpRequest, textStatus) {
var headers = XMLHttpRequest.getAllResponseHeaders();
}
+1 to PleaseStand
and here is my other hack:
after searching and found that the "cross ajax request" could not get response headers from XHR object, I gave up. and use iframe instead.
1. <iframe style="display:none"></iframe>
2. $("iframe").attr("src", "http://the_url_you_want_to_access")
//this is my aim!!!
3. $("iframe").contents().find('#someID').html()

IE not show newest data

I use AngularJS to get data from server. It work well in chrome and firefox if data in server changed. But in IE, It does not show the newest data. I think because IE save data in cache so I send request to server to get new data but IE still shows old data.
How to fix this bug.
Try to use this: https://github.com/saintmac/angular-cache-buster
It adds a query string to the requests like ?timestamp=123456789 to disallow IE to cache it.
Basically if you don't want to use that, you have just to add a different query string to the url requested each time. This prevents IE from caching the request.
IE caches the call, and if you are going to send the same call, then IE will return the cached data.
If you are using $http for your calls, then you can simply add the following code in config function
$httpProvider.defaults.headers.common['Cache-Control'] = 'no-cache, no-store, must-revalidate';
$httpProvider.defaults.headers.common['Pragma'] = 'no-cache';
$httpProvider.defaults.headers.common["If-Modified-Since"] = "0";
However, if you are using jQuery or even $http (another solution), add timestamp in the call along with existing parameters.
jQuery.ajax({
url: "your_url",
data: {
param1 : value1 ,
timestamp : new Date().getTime()
},
success: successCallbackFn
});

Ajax requests are not cached by jQuery

I am using below code for making ajax request. I am trying to determine request are cached or not by using chrome tool. In request tab i see all datas always pulled from server and there is no any "cache" in status text column.
How can i detect that request are cached or not. And I think result are not cached so what is wrong on my code ?
$.ajax({
url: $(this).attr('href'),
dataType:'html',
cache:true,
success: function (data) {
}
});
cache is by default set to true for HTML. If you sent to false jQuery adds a parameter in a query as in '_=201105XXXX".
If the query was not part of the URL, it means that the request page was cached.

$.jsonp not caching

I'm using the third party jsonp library for jquery. In the call to it, you can set cache to true.
However, upon checking in a HTTP sniffer, it appears that all requests are still being sent to the server..
This with the picasa, flickr, and youtube API.
What could be causing this behavior? It does not appear to be browser-specific as I have tested it in multiple browsers and all behave the same (not caching).
The URLs called don't change from one request to the other and the call looks like this:
$.jsonp({
url: url,
cache: true,
async: false,
dataType: 'jsonp',
data: $.extend({ url: options.dataUrl, method: lookupData.method }, fixedOptions),
callbackParameter: "jsoncallback",
success: function(data)
{
$.extend(datasourceOptions, lookupData.onData(data));
getData();
}
});
The only "weird" thing about my setup is that the script that will call the .jsonp is included via a .ajax call itself.. Could that be the issue here? Sounds far fetched but...
Thanks,
Wesley
Edit: Ok, 3 out of the 4 have Expires headers set..
However, the fourth does not and only has these:
Cache-Control: private
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Connection: close
(this is flickr)
What's going on there?
Also, is it not possible to override the header caching directives via jquery somehow?
Cache Headers
First off the server responding to your jsonp calls must have some an expiration date in the response headers. As you mentioned you are not in control of how youtube, flickr, etc answer the jsonp calls.
Browser Cache
The browser is caching the calls with acceptable headers for each unique url.
jQuery JSONP Callback and Identifier
jQuery sends two pieces of data that make your URLs unique. If you do do not change these two options, your jsonp calls will never cache. Read more here
The actual callback= param value that your json data is padded with. Looks something like this: callback=jQuery_123971236127631276.
A unique identifier that makes every URL unique and hence non-cachable. Looks something like this: _=123918712387612398.
Disable unique JSONP Callback
The get param called callback is given a random name generated by jQuery so that many jsonp calls can be fired at once and the responses would not interfere with each other. None the less this must be changed if you wish to cache a certain jsonp call. The attribute jsonpCallback is used to overwrite this feature.
$.jsonp({
url: url,
dataType: 'jsonp',
data: $.extend({ url: options.dataUrl, method: lookupData.method }, fixedOptions),
// Note: using success : function(){ ... } will not be
// called if 'jsonpCallback' attribute is set.
jsonpCallback : 'myCallback',
});
Disable unique URL Identifer
This URL Identifier is set in the param list so that each call is unique, looks like: ...&_=1231981238712. Removing this feature can be done by adding attribute cache : true to your options.
$.jsonp({
url: url,
dataType: 'jsonp',
data: $.extend({ url: options.dataUrl, method: lookupData.method }, fixedOptions),
// Note: using success : function(){ ... } will not be
// called if 'jsonpCallback' attribute is set.
jsonpCallback : 'myCallback',
// Disables: ... &_=1231829812386
cache : true
});
I expect that the services you're calling are returning cache control headers that tell the browser not to cache the response / to expire the cached response very quickly. You should be able to see them in the HTTP messages. Look for Cache-Control and/or Expires, that sort of thing.
Re your edit:
Also, is it not possible to override the header caching directives via jquery somehow?
I don't think so, no, certainly not with JSON-P, which is at its heart a script element being added to the page, so programmatic control over that is going to be extremely limited. Even if it were XHR, frankly, I don't think there's a way to tell the browser to use a cached version that's stale according to its source.
If this is happening within the page lifecycle, you could cache the result yourself in an object on the page, but I'm guessing you're talking about caching between visits to the page (though I can't immediately see why you want to defeat the origin's definition of fresh/stale).

Categories