How to avoid unwanted Ajax and JSON caching in ASP.NET MVC4 - ajax

I'm having a problem with our ASP.NET MVC4 web application:
Our web application is used for realtime data visualization of values and parameters of different industrial devices. When a typical monitoring page gets opened in a client's browser, the page itself is static at first. When the document has finished loading, the current values for the datapoints on this page get loaded via an ajax call from the database. The call returns JSON data that feeds the viewmodel, which is then used by Knockout.js to update the UI elements with the data.
After this initial loading of current data, any upcoming changes to any of the currently displayed datapoints are transmitted from the server to the page via the WebSocket protocol and are then put into the viewmodel, replacing the old values. The new data also gets immediately written to the database, so that an ajax call would always deliver the up-to-date values.
So far, everything works really stable and fast in all HTML5-capable browsers - except for Internet Explorer 10. I'd like to add: OF COURSE ;-)
The problem in detail:
When I open a specific page with some datapoints, it loads the page. The current values get correctly fetched from the DB with ajax. Then, new values arrive and they are shown correctly with the mechanisms described above. The values in the UI get updated.
Now I change to another page, wait for it to get loaded completely, and then I go back to the first page (it doesn't matter if I do this with the "Go Back" button or by clicking a link or entering the URL manually), the page does NOT display the current values, but the values that had been loaded initially in step one via ajax.
The confusing thing is: I verified that the database DOES contain the up-to-date values and not the values shown on the page, therefore they should have get loaded with the initial ajax call when returning to the first page. The annoying thing: they DO get loaded in Firefox, Chrome, and even IE9 etc - but not in IE10.
Is there some new caching mechanism in IE10? How can I resolve this issue? Besides that: as far as I can see, it looks like there's some kind of Ajax / JSON caching going on here, are there ways to definitely prohibit HTML and JSON caching completely / globally in my ASP.NET MVC4 project or IIS?
Thanks for your help!

The jQuery AJAX method allows you to turn caching off:
$.ajax({
url: "test.html",
data: 'foo',
success: function(){
alert('bar');
},
cache: false
});
If this does not solve you can use the querystring trick:
$.ajax({
url: "test.html"+'?ts=' + $.now(),
...
cache: false
});
Anyway the cache: false will do the trick. If not maybe you are using an old jquery version and it is better to upgrade.

Related

Unable to Successfully Update Page Content via ajax

I have a mobile version of a website built in jQuery mobile and living on a dedicated "m.myurl" subdomain. The full desktop version of the site is in Wordpress. My goal is to have updates entered via Wordpress to the desktop site to show up dynamically on the mobile site as well. I am generating the page content from the individual pages of the desktop site via JSON feeds, and have confirmed that the JSON feeds are good (i.e.: if I enter their URL into a browser, I get a good JSON object). However, the AJAX call on the jQuery mobile site refuses to work. I have debugged to the point that I am not receiving any errors in my console, but when I attempt to log the response from the AJAX call to troubleshoot, it consistently shows in the log as undefined, so I am not receiving known good JSON objects.
The functions I'm using to make the AJAX call are as follows:
function processResponse(response){
var update = $(response).find('content');
$('.content').append($(update).html());
};//ends processResponse
function processJSON(url){
$.ajax({
url: url,
data: null,
success: processResponse,
dataType: 'jsonp',
});//ends ajax
};//ends processJSON
I've set the three JSON URL's equal to variables, but have tried calling the function with the URL passed in instead of the variable, to no effect. The 'processJSON" function is called within the content div of each page section of the jQuery mobile index.html file within a $(document).ready.I'm using 'jsonp' as the dataType, as I assume that calling from a subdomain to a main-level domain would be considered a cross-domain call. That said, I'm trying to get this to work locally, and haven't placed it on a test server yet.
Any assistance is appreciated. Thanks!

AJAX GET-request appears in URL bar after refreshing the page in Tomcat that gets restarted

My web app runs under Tomcat, it uses AJAX requests very intensively, and during the development process I have to redeploy the web app intensively too. After the redeployment I usually simply refresh the page knowing that the user session is dropped, but I always get to the scenario described below:
Go to some page, a really big page with many JS-scripts included, that actually makes those intensive AJAX requests.
Stop Tomcat or redeploy the web app.
Refresh the page.
Enter the credentials in the sign-in form to authenticate.
Suddenly get the last AJAX request response in the browser window and the AJAX request URL in the URL bar.
Wow... It looks strange for me that AJAX request URLs appear in the URL bar along with their response in the web page display area. This actually happens to Firefox and Chrome (haven't tested it in other browsers). Unfortunately, I cannot reproduce the same behavior in a simple page written from scratch. Frankly speaking, I don't really understand what happens to such requests and why do browsers "think" if AJAX requests/responses are entered in URL bar by user...
Your possible explanations or hints for such a strange behavior are very and very appreciated. Thanks!
(Perhaps it can help: All AJAX requests are performed with jQuery 1.4.2)
I'm very sorry, as I understood later, the question is not complete, because there was another pitfall I didn't mention, so no one couldn't answer the question in principle. The reason of the bug was hiding in the... <body onunload="..."> tag definition. That was quite unexpected, but that code contained some AJAX request that must be invoked when a user leaves the page. I only realized that the authenicating module (FORM, j_security_check) returned a response (HTTP 302) containing the Location header - so that was the reason why browsers did redirects.
The exact scenario was like that:
Open the page containing <body onunload="some_ajax_here">.
Log out the app using another tab so you could stay at the same page.
Refresh the page so some ajax could be invoked - this AJAX request is not now allowed because it's a secured part of the application (you get the forwarded content of the login page).
Enter the credentials and now oops you get to the result of some ajax directly in the browser window.
As the quick fix, and I hope the final one, I added another request following that AJAX request:
$.ajax({
async: true,
method: "GET",
url: document.location.pathname + document.location.search
});
So the HTML page script simply makes self-page request the last one - j_security_check returns the Location referring the last used HTML page, and the redirect works fine. Perhaps my explanation is not clear and may be not complete or even full of mistakes, but it looks like that in general. I'm very sorry once again, and thank you #ChristopherSchultz!

is it possible to do partial postback on web?

I read some paragraphs in a book saying that it is not possible to do a partial postback for web, even AJAX is employed. Ajax will postback everything and update only ajaxfied controls.
However, on pages I made using ajax, I used Fiddler to monitor the transportation. I found when the page initial load, it loaded everything include pictures .... However, when I click a button and do a ajax postback. I can only see the some data were loaded.... Looks like it doesn't need to reload the whole page again.
I don't know if what I see is correct? Or the book I read is correct?
Thank you guys.
That depends what you put in the term "postback".
The AJAX call will send the complete form data back to the server, just as if the form was posted normally. The server will answer with a partial response that only contains the parts of the page that should be updated.
So, the request is not partial, but the response is.
I am not sure how you are posting back from the client side. I am guessing you are using UpdatePanels. How well you 'AJAX-ify' a web page depends on what method you employ.
UpdatePanels - Read Dave Ward's posting on them - http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/
PageMethods to post back to a web service, get the data and update the DOM to display the result
JQuery and other such AJAX frameworks to post back to a web service
I am sure the link above should clear things up a bit
I'm having a hard time understanding your terminology. I'm not really sure what a "postback" is, much less a "partial" one. I do know that one of the basic ways to transmit information to an HTTP server is via a POST request, which is usually used when submitting forms. If you mean to say that the entire form is transmitted when you click a submit button, I believe you'd be right.
You also seem to be doing something with AJAX, but it's difficult to tell. The whole point of AJAX is to have dynamic data displayed on a page without resorting to reloading it. Defining what to send and what to do with the results is entirely up to your own JavaScript. So unless you're using a framework, which you don't specify, there is no such thing as "ajaxified controls."
In any case, "AJAX" usually means using the XMLHttpRequest() method of modern browsers to send data to servers without refreshing the page. When you call this function, you specify exactly what data to send. This has nothing to do with HTML forms. One caveat: if you are indeed using a library for AJAX, it might impose additional limits on how you structure information to send.

Iframe vs normal / ajax get request

I have a page that gathers environment status from a couple of IBM WebSphere servers using iframes similar to this:
<iframe src="http://server:9060/ibm/console/status?text=true&type=server&node=NODE&name=ServerName_server_NODE"></iframe>
and it happily prints out "Started" or "Unavailable" etc. But if I load the same url in a normal browser sometimes it works, sometimes it does not? Some of them are showing a login page, while others are simply return HTTP code 500.
So whats the difference between loading the page through an iframe vs through a browser?
I can tell you that the iframe solution works no matter which machine I am doing it on, so I do not belive it has anything to do with the user whos opening the page. And before you ask, why not keep the solution that works, well its because it takes a long time to open the page with the iframes vs a page where everything is requested through ajax.
Update: Using jQuery to perform the ajax call returns "error" and "undefined" for the servers that I can't see in a normal browser.
One difference is an iframe has to render the view while XHR would not.
An iframe is essentially the same as opening with the browser. In both cases the browsers credentials are used, so there will be no difference between the two.
Secondly, loading something in an iframe should take the same amount of time as requesting it through XHR, since in both cases the browser makes an HTTP request and waits for the response. Although I should add that an iframe will take time to render the content onto the page. However if you plan on displaying it with ajax anyways, an iframe/xhr solution will be more or less the same.
In case of ajax request same origin policy (which restricts cross domain call) comes into picture. So you can't make cross domain call using xhr. Alternative for same is embed flex swf file in your page as activex control and make flex call through javascript and then flex is responsible to make cross domain call (flex can if targeted domain allows cross domain using crossdomain.xml) and renders result using javascript again.

Modify Address Bar URL in AJAX App to Match Current State

I'm writing an AJAX app, but as the user moves through the app, I'd like the URL in the address bar to update despite the lack of page reloads. Basically, I'd like for them to be able to bookmark at any point and thereby return to the current state.
How are people handling maintaining RESTfulness in AJAX apps?
The way to do this is to manipulate location.hash when AJAX updates result in a state change that you'd like to have a discrete URL. For example, if your page's url is:
http://example.com/
If a client side function executed this code:
// AJAX code to display the "foo" state goes here.
location.hash = 'foo';
Then, the URL displayed in the browser would be updated to:
http://example.com/#foo
This allows users to bookmark the "foo" state of the page, and use the browser history to navigate between states.
With this mechanism in place, you'll then need to parse out the hash portion of the URL on the client side using JavaScript to create and display the appropriate initial state, as fragment identifiers (the part after the #) are not sent to the server.
Ben Alman's hashchange plugin makes the latter a breeze if you're using jQuery.
Look at sites like book.cakephp.org. This site changes the URL without using the hash and use AJAX. I'm not sure how it does it exactly but I've been trying to figure it out. If anyone knows, let me know.
Also github.com when looking at a navigating within a certain project.
It is unlikely the writer wants to reload or redirect his visitor when using Ajax.
But why not use HTML5's pushState/replaceState?
You'll be able to modify the addressbar as much as you like. Get natural looking urls, with AJAX.
Check out the code on my latest project:
http://iesus.se/
This is similar to what Kevin said. You can have your client state as some javascript object, and when you want to save the state, you serialize the object (using JSON and base64 encoding). You can then set the fragment of the href to this string.
var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;
document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history
The first way will treat the new state as a new location (so the back button will take them to the previous location). The latter does not.
SWFAddress works in Flash & Javascript projects and lets you create bookmarkable URLs (using the hash method mentioned above) as well as giving you back-button support.
http://www.asual.com/swfaddress/
The window.location.hash method is the preferred way of doing things. For an explanation of how to do it,
Ajax Patterns - Unique URLs.
YUI has an implementation of this pattern as a module, which includes IE specific work arounds for getting the back button working along with re-writing the address using the hash. YUI Browser History Manager.
Other frameworks have similar implementations as well. The important point is if you want the history to work along with the re-writing the address, the different browsers need different ways of handling it. (This is detailed in the first link article.)
IE needs an iframe based hack, where Firefox will produce double history using the same method.
If OP or others are still looking for a way to do modify browser history to enable state, using pushState and replaceState, as suggested by IESUS, is the 'right' way to do it now. It's main advantage over location.hash seems to be that it creates actual URLs, not just hashes. If browser history using hashes is saved, and then revisited with JavaScript disabled, the app won't work, since the hashes aren't sent to the server. However, if pushState has been used, the entire route will be sent to the server, which you can then build to respond appropriately to the routes. I saw an example where the same mustache templates were used on both the server and the client side. If the client had JavaScript enabled, he would get snappy responses by avoiding the roundtrip to the server, but the app would work perfectly fine without the JavaScript. Thus, the app can gracefully degrade in the absence of JavaScript.
Also, I believe there is some framework out there, with a name like history.js. For browsers that support HTML5, it uses pushState, but if the browser doesn't support that, it automatically falls back to using hashes.
Check if user is 'in' the page, when you click on the URL bar, JavaScript says you are out of page.
If you change the URL bar and press 'ENTER' with the symbol '#' within it then you go into the page again, without click on the page manually with mouse cursor, then a keyboard event command (document.onkeypress) from JavaScript will be able to check if it's enter and active the JavaScript for redirection.
You can check if user is IN the page with window.onfocus and check if he's out with window.onblur.
Yeah, it's possible.
;)

Resources