I'm having a serious issue with Internet Explorer caching results from a JQuery Ajax request.
I have header on my web page that gets updated every time a user navigates to a new page. Once the page is loaded I do this
$.get("/game/getpuzzleinfo", null, function(data, status) {
var content = "<h1>Wikipedia Maze</h1>";
content += "<p class='endtopic'>Looking for <span><a title='Opens the topic you are looking for in a separate tab or window' href='" + data.EndTopicUrl + "' target='_blank'>" + data.EndTopic + "<a/></span></p>";
content += "<p class='step'>Step <span>" + data.StepCount + "</span></p>";
content += "<p class='level'>Level <span>" + data.PuzzleLevel.toString() + "</span></p>";
content += "<p class='startover'><a href='/game/start/" + data.PuzzleId.toString() + "'>Start Over</a></p>";
$("#wikiheader").append(content);
}, "json");
It just injects header info into the page. You can check it out by going to www.wikipediamaze.com and then logging in and starting a new puzzle.
In every browser I've tested (Google Chrome, Firefox, Safari, Internet Explorer) it works great except in IE. Eveything gets injected just fine in IE the first time but after that it never even makes the call to /game/getpuzzleinfo. It's like it has cached the results or something.
If I change the call to $.post("/game/getpuzzleinfo", ... IE picks it up just fine. But then Firefox quits working.
Can someone please shed some light on this as to why IE is caching my $.get ajax calls?
UPDATE
Per the suggestion below, I've changed my ajax request to this, which fixed my problem:
$.ajax({
type: "GET",
url: "/game/getpuzzleinfo",
dataType: "json",
cache: false,
success: function(data) { ... }
});
IE is notorious for its aggressive caching of Ajax responses. As you're using jQuery, you can set a global option:
$.ajaxSetup({
cache: false
});
which will cause jQuery to add a random value to the request query string, thereby preventing IE from caching the response.
Note that if you have other Ajax calls going on where you do want caching, this will disable it for those too. In that case, switch to using the $.ajax() method and enable that option explicitly for the necessary requests.
See http://docs.jquery.com/Ajax/jQuery.ajaxSetup for more info.
As marr75 mentioned, GET's are cached.
There are a couple of ways to combat this. Aside from modifying the response header, you can also append a randomly generated query string variable to the end of the targeted URL. This way, IE will think it is a different URL each time it is requested.
There are multiple ways to do this (such as using Math.random(), a variation on the date, etc).
Here's one way you can do it:
var oDate = new Date();
var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds();
$.get(sURL, null, function(data, status) {
// your work
});
Gets are always cacheable. One strategy that may work is to edit the response header and tell the client to not cache the information or to expire the cache very soon.
If you are calling ashx page you can also disable caching on the server with the following code:
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
this is what i do for ajax calls:
var url = "/mypage.aspx";
// my other vars i want to add go here
url = url + "&sid=" + Math.random();
// make ajax call
it works pretty well for me.
NickFitz gives a good answer, but you'll need to turn the caching off in IE9 as well. In order to target just IE8 and IE9 you could do this;
<!--[if lte IE 9]>
<script>
$.ajaxSetup({
cache: false
});
</script>
<![endif]-->
The answers here are very helpful for those who use jQuery or for some reason directly use the xmlHttpRequest object...
If you're using the auto-generated Microsoft service proxy its not as simple to solve.
The trick is to use Sys.Net.WebRequestManager.add_invokingRequest method in the event handler change the request url:
networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + '&nocache=' + new Date().getMilliseconds();
I've blogged about this: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/
Just wrote a blog on this exact issue only using ExtJS (http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html
)
The problem was as I was using a specific url rewriting format I couldn't use conventional query string params (?param=value), so I had write the cache busting parameter as a posted variable instead..... I would have thought that using POST variables are a bit safer that GET, simply because a lot of MVC frameworks use the pattern
protocol://host/controller/action/param1/param2
and so the mapping of variable name to value is lost, and params are simply stacked... so when using a GET cache buster parameter
i.e. protocol://host/controller/action/param1/param2/no_cache122300201
no_cache122300201 can be mistaken for a $param3 parameter which could have a default value
i.e.
public function action($param1, $param2, $param3 = "default value")
{
//..//
}
no chance of that happening with POSTED cache busters
If you are using ASP.NET MVC, it is enough to add this line on top of the controller action:
[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{
}
IE is within its rights to do this caching; to ensure the item isn't cached, the headers should be set accordingly.
If you are using ASP.NET MVC, you can write an ActionFilter; in OnResultExecuted, check filterContext.HttpContext.Request.IsAjaxRequest(). If so, set the response's expire header: filterContext.HttpContext.Response.Expires = -1;
As per http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/:
Some people prefer to use the Cache - Control: no - cache header
instead of expires. Here’s the difference:
Cache-Control:no-cache – absolutely NO caching
Expires:-1 – the browser “usually” contacts the
Web server for updates to that page via a conditional
If-Modified-Since request. However, the page remains in the disk cache
and is used in appropriate situations without contacting the remote
Web server, such as when the BACK and FORWARD buttons are used to
access the navigation history or when the browser is in offline mode.
Related
This is code work fine:
{html}
{head>
{**link rel="stylesheet" href="http://localhost:3000/CSS/mystyle.css"**}
{/head}
{body}
{/body}
{/html}
But this code with same url give me problem:
XMLHttpRequest cannot load "href="http://localhost:3000/CSS/mystyle.css". Origin null is not allowed by Access-Control-Allow-Origin.
$(document).ready(function() {
var href = 'http://localhost:3000/CSS/mystyle.css';
$.ajax({
url: href,
dataType: 'text/css',
success: function(data) {
$('\n' + data + '').appendTo("head");
}
});
});
Really don't understand what is problem, both call HttpRequest ?
Thanks, for any help.
The simplest answer will be to use a local web server like WAMP(or IIS) if you are not already.
the second answer is
Chrome and Safari has a restriction on using ajax with local resources. That's why it's throwing an error like
Origin null is not allowed by Access-Control-Allow-Origin.
Solution: Use firefox or upload your data to a temporary server. If you still want to use Chrome, start it with the below option;
--allow-file-access-from-files
More info how to add the above parameter to your Chrome: Right click the Chrome icon on your task bar, right click the Google Chrome on the pop-up window and click properties and add the above parameter inside the Target textbox under Shortcut tab. It will like as below;
C:\Users\XXX_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files
I have a JavaScript class that displays a partially-opaque div over top of the content of another div when an Ajax request is sent to the server.
When the request returns, the JavaScript class hides the partially-opaque div....it works great...sort of.
Right now, in IE9, when the Ajax request is complete, the partial-opacity is only hidden if the user moves their mouse.
So, my question is, how do I force the browser to do what it's supposed to do?
This is my extremely simple function that is called after the request returns to the browser:
_hideBlockingDiv: function() {
if (this.get_blockingDivClientID()) {
var blockingElement = $get(this.get_blockingDivClientID());
if (blockingElement != null) {
blockingElement.style.display = 'none';
//I know that this method is executing correctly because I "hi" showed
//up properly...but the element remained visible:
blockingElement.innerHTML = 'hi';
}
//if I add the alert then everything works fine in IE9
//if I don't then the page will remain the same until the user moves their mose
//alert("done");
}
}
Please note that I am not using JQuery.
I am using the AJAX.NET library since I am a .NET developer (and JQuery didn't become popular until years after I implemented my Ajax-enabled server controls)
Thanks
-Frinny
How and where do you call the _hideBlockingDiv function from? Since you are using MS Ajax library, you might want to have a page loaded handler on client side and call this function from within that handler. So basically
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function(){
_hideBlockingDiv();
});
Hope this helps!
It turns out that the problem only exists in the beta version of IE9 that I was using at the time. This problem went away once the full version of IE9 was released.
Hi
I want to know How to make the page reload asynchronous, for example if someone has received a message , the last message will appear without refreshing the page. just like facebook. thank you.
You would have to use something like JQuery & Javascript to poll the server for changes and display them on the page in a div.
setInterval('someFunc()', 1000)
function someFunc()
{
$.ajax({
async: true,
type: "GET",
url: "www.domain.com/url",
data: data,
success: function (html) {
$("#myDiv").html(html);
}
});
}
This will update the div with ID myDiv every second with the data from www.domain.com/url passing in data is a param (you will have to define 'data')
well there is alot of approaches
but the basics is that you call an ajax function every second or so that
checks with external php/asp or whatever file if any changes has been made to your
database/text if so
append it to the chatbox.
p.s. using libraries such as jquery simplifies things alot
Or you can use Comet model, it doesn't stress the network so much and does not fill the web servers access logs so much. The responses are also faster. Commet means that the HTTP server pushes the data to you immediately when they appear.
just need tips on how to make forms where request are submitted via AJAX with a loading progress image. I am using update panels with AJAX framework. I would like to know about the recommended approach. Through JQuery or AJAX toolkit ?
Please advice, examples would be an added bonus for me.
1- Prepare a client side div with "display:none" style property. put your loading image inside.
2 - when the user or page submits a request, change that divs display property to "block".
3- Add some kind of "information received" sign to the response and check this response from the client side and then change that divs display property back to "none"
I would like to know about the
recommended approach
Well, that depends on what you are doing, what parts of the form are you updating, how big is the form, what values are you sending to the server.
Generally speaking, if you want to update something simple (dropdownlist, listbox, etc), youd generally use JavaScript (or jQuery) to call an AJAX-enabled web service. This way, you're only sending to the server the data it needs, things like ViewState/cookies are not sent over the wire. You also have full control over the pre/post execution events (so you can add your loading images, call the WS, then clear them).
However, if you want to asynchronously update an entire form (which has a lot of controls), you're probably right in using an UpdatePanel. Things like a GridView are a good case for an UpdatePanel (as you usually need to handle editing, binding and paging all asynchronously).
The progress image is made easy with the following code:
<ProgressTemplate>
<img src="someloadingimage.gif" alt="Loading" />
</ProgressTemplate>
Stick that inside your UpdatePanel, and whenever an AJAX call is made, the loading image will be shown.
HTH
If you use JQuery for AJAX request then you can use the following events -
$.ajax({ url: "test.html",
type: "GET",
beforeSend: function(){
-----load your loader here-----
});,
success: function(){
------remove your loader here -----------
Remaining code
}});
You can also use POST. in above example i have used GET.
For detailed documentation you can refer - http://api.jquery.com/jQuery.ajax/
Create a small plug-in for your loader like so.
$.fn.ShowLoader = function(on){
switch(on)
{
case true:
$(this).show();
break;
default:
$(this).hide();
break;
}
}
then use the following:
$('form').submit(function(){
var Form = $(this);
$('.loader',Form).ShowLoader(true);
//Gather some params
Location = Form.attr('src');
Data = Form.Serialize();
$.post(Location,Data,function(result){
result = result || false;
if(result)
{
$('.loader',Form).ShowLoader(false); //Disable the loader
//Process result
}
});
})
html would just be a regular form, with an image / div inside with the class of loader
How do I POST to a web page using Firebug?
You can send POST request to any page by opening console (e.g. in FireFox ctrl + shift + k) and typing simple JS:
var formPost = document.createElement('form');
formPost.method = 'POST';
formPost.action = 'https://www.google.com'; //or any location you want
document.body.appendChild(formPost);
formPost.submit();
AFAIK Firebug can't do this. However, there is a very useful Firefox extension, in the spirit of Firebug, called Tamper Data. This should be able to do what you want.
It allows you to monitor each request made by the browser, and you can turn on an option that allows you to look at, and edit, every single request before it gets sent.
Firefox 27 (maybe earlier versions too, never checked) has built-in developer tools to modify and resend requests. If you don't have Firebug installed, the console is available by pressing the F12 key. If Firebug is installed, press Ctrl+Shift+K instead.
I know this is an old question, but I recently stumbled upon the same problem and wanted to share the method I am using.
Assuming the web site you want to POST to has a form with method="POST" (a very likely scenario), you can use Firebug's JavaScript command line to programmatically submit a POST request. Just click the "Show Command Line" icon in Firebug and enter something like this in the narrow text box at the very bottom of the window:
document.forms[0].submit()
Maybe this helps someone.
Another simple solution is to load any webpage that uses jQuery, and type up a $.post() in the console.
HTTP resource test is a firefox plugin that can do this.
Another powerful Firefox plugin to perform post request and some more features is the Hackbar.
Related:
To resend a POST already made, right click the POST request in the Net/XHR view and click "Resend".
Using Firebug 1.12.0:
Got here looking for a Firebug way of doing this. Then I realized that I could use Fiddler. This is the most powerful tool I know when it comes to debugging web requests.
Fiddler The free web debugging proxy for any browser, system or
platform
Click the Composer tab and write your request as desired - then click Execute.
NO NEED of plugins !!
Just drag any url in BOOKMARK BAR, then right click and EDIT, and insert javascript code:
javascript:var my_params=prompt("Enter your parameters","var1=aaaa&var2=bbbbb"); var Target_LINK=prompt("Enter destination", location.href); function post(path, params) { var form = document.createElement("form"); form.setAttribute("method", "post"); form.setAttribute("action", path); for(var key in params) { if(params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } } document.body.appendChild(form); form.submit(); } parsed_params={}; my_params.substr(1).split("&").forEach(function(item) {var s = item.split("="), k=s[0], v=s[1]; parsed_params[k] = v;}); post(Target_LINK, parsed_params); void(0);
then enter the target site-link, and click that button in BOOKMARK BAR! That's all!
( source: https://stackoverflow.com/a/38643171/2377343 )