I'm building an iPhone app that displays a UIWebView pointing to a web application I've created.
The web application makes frequent web service calls for data items which are used to animate controls on a canvas. The calls for data use jQuery ajax, passing parameters via JSON and receiving an XML response.
I'm finding that while user interactions with the UIWebView are occurring, the javascript setTimeout method is blocked and doesn't seem to execute at all. Fair enough; there are ways around this.
But the major problem is that every now and then after user interactions (zooming, panning etc), the ajax web service calls will just fail all the time and I can't establish a reason why. Even if they are made repeatedly, for the next few minutes none of them will even get through to the web service. If you completely leave the UIWebView alone, they will never fail as long as the web service is up and connectivity is present.
Can anyone suggest why, and how to fix/work around this?
Quick update: according to the Safari mobile debugger, the 'response' object in the error function is undefined. (It works if, for example, I make the URL invalid. This can then be called from objective-c by [webView stringByEvaluatingJavascript:#"lastError"], but throws an exception for this 'touched the uiwebview' error):
$.ajax({
type: "POST",
url: "WebService.asmx/GetValues",
async: true,
data: "{'pageVersionIndex': " + PageVersionIndex + " , 'timeStreamIndex': '" + TimeStream + "'}",
contentType: "application/json; charset=utf-8",
dataType: "xml",
success: function (response) { UpdateControls(response); },
error: function (response, status, errorthrown) {
calling = false;
lastError = response.statusText; //Throws exception
connectionInterrupted = true;
DataRoutine = window.setTimeout(DataService, dataFrequency); }
});
I'm afraid you are toasted... in a way. In iOS Safari and in UIWebView respectively system processes have priority over browser and if there is a sudden demand for more CPU power or memory for native processes (like handling touch etc) it might happen that any running javascript will be stopped from executing to reduce the memory load or cpu usage. The worst part is that it won't throw any errors or anything... it just stops your code execution as if nothing happened.
Afraid that if it happens a lot in your app the only way would be to add some kind of timer that would listen if the request wasn't blocked if so - do it again until successful.
Ups and downs of iOS - they really like you to go native rather then web :)
hope it helps,
Tom
Related
I was calling an ajax function on load page event. When I load the page, in the server log, There was not existing call log(I log entrance and out on all mvc server method). The request from javascript to server was taking some time, 2 to 3 minutes. The strange thing is when I test it local and test server, it works well. It occurs just when I deploy a project to the real server!
I found some posts about the method to do ajax, xmlhttp, $.ajax(). I already used both. But It still exists.
This is my javascript code.
$(document).ready(function () {
$.ajax({
type: "GET",
url: allservicesUrl,
async: true,
success: function(result, status, xhr){
var services = JSON.parse(xhr.responseText);
for (i in services) {
createServicecard(services[i]);
}
},
error: function(xhr, status, err) {
alert(xhr.responseText);
}
});
})
I wanna execute it immediately. How do I correct this problem?
Thanks for the advice.
I saw an answer and comments. Then, I saw the dev tool(network tab), finally, I found the problem.
Now I correct it, it works well. Thank you very much.
ps. Problem: connecting the internet in closed network.
Use the debugging/developer tools in your browser to trouble shoot this issue.
look in the console and see if you have any JS errors, then look in the network tab. Clear the entries and then reload the AJAX call.
you should be able to see if your script is slow to send the request to the server or if the server is slow to answer.
until you figure out if the bottleneck is in the script or on the server you can't fix it.
I will do my best to explain my problem to avoid people pointing me into different directions.
I got an assignment from business people. I don't know the terminology. It is very similar to email notification, message notification on facebook, notification on social media games.
For example, people are sending 20 email messages 5 minutes ago. the screen will display 20 (see attachment). Now, 3 more messages have arrived, the web page should update the number to 23.
Facebook has similar concepts when our friends like/comment message. The notification changes. Same thing is true on social media game. Any status changes on our game, it will reflect it.
I kind of have idea on how to do it cosmetically (on CSS). How to do it using javascript/asp.net. Do I need to postback in order to refresh the message. I never pay attention to that on facebook/yahoo email/social media games. All I know is something is happening, the webpage is updating the status.
Sorry the question is too broad. If someone can help me to point to the right direction, I appreciate any help
HTML5 introduced a very interesting concept call Server-Sent Events in which server can dynamically connect to the client and send data.
Eg:
var source = new EventSource("demo_sse.asp");
source.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data + "<br>";
};
And on server side you can write,
<%
Response.ContentType = "text/event-stream"
Response.Expires = -1
<!--Writing "data:" is important-->
Response.Write("data: The server time is: " & now())
Response.Flush()
%>
However, some old browsers may not support this.
One other way to accomplish this task is to use Ajax call as,
function checkNewMessages(totalMessages){
return $.ajax({
url: 'demo.asp',
type: 'GET',
cache: false,
data: {
totalMessages: totalMessage;
}
});
}
checkNewMessages(totalMessages).success(function (data) {
// display the data wherever you want
});
//Checking for new messages every 5 seconds
setInterval(checkNewMessages(totalMessages,5000));
Whatever you write within your Write() in server side will be displayed here. Now to constantly check for the new messages you can call the above ajax function with the help of setInterval()
There are many ways to do this, depending on how real time you need it to be.
The most common way is to use JavaScript with an XmlHttpRequest to call an ASP.NET page which returns the number of messages, I recommend you use a JSON object for this. The benefit of this approach allows you to request data from the server without the user experiencing a full page refresh. You can use JavaScript to set it to call every x seconds depending on your requirements.
Collectively that is known as AJAX, using a JavaScript library such as JQuery can make this much easier.
I have a HTML5 application that needs to send a disconnect ajax request when the user changes/refreshes the page. I am currently using this code:
window.addEventListener("beforeunload", function(event) {
$.ajax({
url: api_disconnect,
data: { identifier: token },
method: "GET"
});
});
I don't need to process the response, or even ensure that the browser receives a response. My question is, can I rely on the server receiving the request?
And if not, how can I accomplish this? Currently I have the app send an "I'm alive!" request every 15 seconds (which already feels like too much). I want the server to know the second the user disconnects.
To clarify, I know that if the browser/computer crashes there's nothing I can do about that. That's what the heartbeat is for. I just mean in a normal use case, when the user closes/changes/refreshes the page.
You cannot 100% rely on the ajax call getting through. You can test many browsers and operating systems and determine which ones will usually get the ajax call sent before the page is torn down, but it is not guaranteed to do so by any specification.
The heartbeat like you are using is the most common work-around. That will also cover you for a loss in network connection or a power-down or computer sleep mode or browser crash which the beforeunload handler will not.
Another work-around I've seen discussed is to use a socket.io connection to the server. Since the socket.io connection has both a small, very efficient heartbeat and the server will see the socket get closed when the page is closed, you kind of get the best of both worlds since you will see an abnormal shut-down via the heartbeat and you will see a normal shut-down immediately via the webSocket connection getting closed.
I am working with codeigniter and jquery. I am using ajax to send some info to a codeigniter function to perform a db operation , in order to update the page.
$.ajax({
type: "POST",
url: BASE_URL+"Update/update",
data:{ i : searchIDs, m : message },
dataType: 'json',
success: function(data) {
console.log(data);
},
error: function(data) {
console.log(data);
},
complete: function() {
alert("REFRESHING..");
window.location.href = "pan_controller/reply";
}
});
After the operation is complete I want to reload the page. This works normally in locally on my WAMP. However when I deploy to a shared host I usually have to reload the page manually, (using the reload button in the browser -- screenshot above). I see no errors in firebug. I've tried a variety of fixes but have recently started to wonder if this is a caching issue on my shared hosting server. If so is there a better way to reload using jquery rather than just redirect so as to avoid a cache on the shared host?
Have you established that the complete function is running in those cases when the page doesn't reload? If so then I think you are right, it's a caching problem.
You can try adding a timestamp parameter to the end of the window.location.href value to make it unique each time and avoid any issues with caching, although a better approach would be to send the correct headers back with the response, so that the browser knows not to cache that page.
window.location.href = "pan_controller/reply?t=" + (new Date().getTime());
I’m building a phonegap application using Jquery mobile, I use ajax calls for communicating with tomcat server. All my scripts are located within the application. My first ajax call works and my second ajax call does not work for Windows Phone 8 and it works in Android and iOS.
I’m using single domain and also I’ve used cross domain flags just in case still no luck with second ajax call. I have ajax calls in each of the JQM page, only the ajax call which is in the login page work and all other ajax calls doesn’t work though I get (HTTP 200 OK )as response, I do not see the request in Tomcat log in the server (though I can see first login ajax request).
I think that the jsession ID created during initial ajax call (login) gets lost in some way during navigation to next JQM page.
This is the ajax call I’m using in my application,
request = $.ajax({
url: "http://X.X.X.X/Servlet/Login",
type: “post”,
data: serializedData
});
I have the following flags in the app, though I’m not using a cross domain (all calls are made to same IP).
$(document).bind("mobileinit", function() {
$.support.cors=true;
$.mobile.allowCrossDomainPages = true;
$.mobile.pushStateEnabled = false;
$.mobile.touchOverflowEnabled = false;
$.mobile.defaultPageTransition = 'slide';
$.mobile.defaultDialogTransition = 'pop';
$.mobile.transitionFallbacks.slide = 'none';
$.mobile.transitionFallbacks.pop = 'none';
$.mobile.buttonMarkup.hoverDelay = 0;
$.mobile.phonegapNavigationEnabled = true;
});
I have set data-ajax=“false” in the forms I use.
Also I had to remove event.preventDefault();for Windows Phone 8 other wise after submit button is clicked the page refresh’s with no action being done.
I want to state again that, my code works perfect in Android and iOS (with just cross domain flag added). But in Windows Phone 8, I’m unable to make second ajax call to the same server.
I hope I can fix the issue with your help, any lead will be much appreciated. thanks.
this is likely related to a cache issue - to try and solve this, please try adding a miscellaneous random value in your serialized data. You can reference this
Prevent browser caching of jQuery AJAX call result
i had a similar issue with an ajax call and this random variable solved the problem
I had to enable cookies from internet explorer of Windows Phone 8 to fix my issue. Hope this helps to solve someone’s frustration.
i had the same issue. i disable the cache and fix the issue:
request = $.ajax({ url: "http://X.X.X.X/Servlet/Login",
type: 'post',
data: serializedData,
cache: false
});