jQuery Mobile + Phonegap on Android - no Ajax - android

EDIT: Solution for JQuery Mobile + Phonegap AJAX Problems:
subdomains="true" property in config.xml is not working in phonegap 2.9.0, every request to a subdomain will return 200 but $.ajax won't fire the success function (and $.getJSON won't fire anyways).
Also: Syntax *.domain.tld as stated in the official doc is not working, only way I found to solve that problem: Setting access origin and acces uri to "*" (all)
<access origin="*"/>
<access uri="*"/>
I'm working on a mobile application using the jQuery Mobile Framework and Phonegap.
I've just added an AJAX request to my application which is used to get data from my webserver.
The page is correctly loading but Android (4.1.2) never fires the AJAX event or never gets a request from the Webserver, in fact it's just hanging on the loading spinner.
Strange thing about this is, that I already use an AJAX request to the same server (but with different domain) that works perfectly fine:
$.getJSON("[...]checkupdate.php?callback=?", function(data){
[...]
})
I've tried to do the second request with $.getJSON too and it worked on my computer but failed on Android. I started looking around for a solution and found out, that setting the cache to false in $.ajax might help so I rewrote my code but it's still not working.
$.ajax({
cache : false,
type: 'GET',
url: requestURL,
dataType: 'jsonp',
context: document.body,
success: function(data){
[...]
}});
Is there anything else to do to get this to work?

I found a way to solve that problem. I noticed, that the subdomains="true" property in phonegap's config.xml is not working. (Phonegap 2.9.0). Every request to a subdomain will return status 200 but $.ajax won't fire the success function (and $.getJSON won't fire anyways). The syntax *.domain.tld as stated in the official doc isn't working for me either, only way I found to solve that problem was setting access origin and acces uri to "*" (all)

Related

Basic user authentication works on Android, does not on iOS

I'm building an app that gets data from a server using basic user authentication. This works fine on Android, but on iOS nothing happens. In safari it also works fine.
This is the code I'm using:
$.ajax({
url: main_url+'api-cache/'+slug+'.json?r='+random_number(),
dataType: 'json',
headers: {
'Authorization': "Basic " + btoa(localStorage.getItem('email') + ":" + localStorage.getItem('password'))
}
})
.done(function(result) {
main_url is a link to an https website.
I have als tried username and passwork like the jQuery documentation says and also beforesend, nothing seems to work. Without the authentication it works fine by the way. Also the result seems to be ".done" because no error is fired in ".fail".
Help? Oh and btw, I'm using Phonegap Build.
Problem solved using a couple of headers on the server instead of changing the app: https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/

Issues with ASP.NET Forms Authentication on Phonegap (Android)

I have an ASP.NET MVC/Web API backend where I have implemented a Forms Authentication for my Phonegap app. The login is executed by sending the users credentials via jQuery Ajax call like this:
$.ajax({
type: "POST",
url: "/api/authentication/login",
data: JSON.stringify({ Username: username, Password: password }),
contentType: "application/json; charset=utf-8",
dataType: "TEXT",
statusCode: {
200: function (response, status, xhr) {
// successfully authenticated
Backbone.history.navigate("/", { trigger: true });
}
}
});
The backends login method looks like this:
[ActionName("login")]
[AllowAnonymous]
public LoginResult Login(LoginCredentials credentials)
{
// doing all kinds of things here
// if valid credentials
FormsAuthentication.SetAuthCookie(loginID, true);
return loginResult;
}
I have this in my Web.config:
<authentication mode="Forms">
<forms
name=".ASPXAUTH"
loginUrl="/login"
defaultUrl="/home"
protection="All"
slidingExpiration="true"
timeout="525600"
cookieless="UseCookies"
enableCrossAppRedirects="false"
requireSSL="true"
>
</forms>
</authentication>
Now the problem with Android here is that the cookie is properly set and it does work on my authorized methods after the login, but sometimes (often) when I close the app and open it again, I'm no longer logged in. The cookie isn't there anymore, I can not see it in the request. This should not happen because I have set the timeout to 525600. I have noticed that this problem often occurs when I close the app immediately after login. In other hand if I log out and then log in without closing the app, the cookie is saved properly.
But, if I get the cookie to stick, most of the time the logout behaves strangely as well. This is how I do the logout request:
$.ajax({
type: "POST",
url: "/api/authentication/logout",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "text"
success: function (response) {
// successfully logged out
Backbone.history.navigate("api/login", { trigger: true });
}
});
The backend:
[ActionName("logout")]
[AllowAnonymous]
public String Logout()
{
FormsAuthentication.SignOut();
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
cookie.Expires = DateTime.Now.AddYears(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
return "home";
}
Now similar to the problem with the login, the logout first seems to be successful and the cookie is no longer sent with any requests. But when I close the app and open it again, the cookie is back and I'm logged in again. I can see that the cookie has the same value as the one I thought I just removed by setting its expiration time to the past.
I have tried all kinds of tricks, like:
extra reloads after the login/logout (location.reload())
executing the logout/login request multiple times
executing request to other methods after the login/logout
1-10 second timeout between the login/logout request and the reload
all kinds of variations of the above
The authentication works as intended on iOS and Windows Phone. The problem occurs only on Android (tested on KitKat and Lollipop). No problem on the Android emulator, but on real devices and Visual Studios Android emulator this happens all the time.
I don't know in which direction to go from here. Is there something in the Android WebView that could cause this kind of behavior? Is there something else I could test out? Please help!
I'm more than happy to give more information if needed.
EDIT:
Inspired by Fabian's comment, I changed the logout method to this:
FormsAuthentication.SignOut();
HttpCookie cookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName];
cookie.Expires = DateTime.Now.AddYears(-1);
HttpContext.Current.Response.Cookies.Clear();
HttpContext.Current.Response.Cookies.Add(cookie);
return "home";
Instead of creating a new cookie, I used the one in the response. It did not work.
I also tried something I found from here: http://techblog.dorogin.com/2013/01/formsauthentication-gotcha-with-signout.html That also did no difference, the path was not the problem. Still looking for a solution.
ANOTHER EDIT:
Still not able to find a solution for this. I had to make a horrible workaround.
Login: I make two reloads after the login and then a request to
a dummy method. This seems to work every time.
Logout: I use a flag placed in localStorage to determine if the user has logged out and perform a logout in the startup. This always removes the cookie correctly.
I'm not happy with these hacks and I'm still hoping for a better solution.
PhoneGap loads files from file:// protocol. Unfortunately, cross origin requests are not allowed and unless you open cross origin requests from all hosts *, this problem will not resolve.
There are multiple ways this can be fixed but they are really long.
Load Html from http://
Load entire website from web server instead of local storage. This removes all issues with cross origin requests. Benefit is you don't need to publish new version of app when you change UI. But you will have to implement very powerful caching and first time opening app will take longer time.
Intercept http:// and deliver local files
As you know, phonegap simply uses WebView, in all platforms, you can simply override Url protocol to inject files from your app's local storage. This will be faster, and browser will think that it is loading html from same resource.
Setup OAuth + custom header for authentication
Redirect to a login page hosted at your website say http://domain.com/api/login
After successful login, use PhoneGap localStorage (not browser's localStorage) to store authorization.
Navigate to your local html pages from app and for each json api request you send to server, send authorization header as separate header in ajax request.
Setup a Authorization module, where you can manually authorize asp.net request if your authorization was sent through custom header in http request
I believe I have found the solution. The Phonegap version on your config.xml file is cli-5.1.1, which includes Android Phonegap version 4.0.2 according to the documentation.
The problem with the versions is it seems the Android Phonegap team eventually fixed the cookie storage problem on version 5.2.0. It can be found in release notes as:
CB-10896 We never enabled cookies on the WebView proper
Therefore, updating your Phonegap to latest version should solve the problem.
According to MSDN:
The FormsAuthentication.SignOut method removes the
forms-authentication ticket information from the cookie.
And that's all you need to log the user out. You don't need to expire or remove your cookie itself. Simply change your Logout() to:
[ActionName("logout")]
[AllowAnonymous]
public String Logout()
{
FormsAuthentication.SignOut();
return "home";
}

phonegap application ajax calls fail after upgrading android from 2.3.3 to 4.0.3

I have developed a mobile application using :
jquery mobile 1.1
jquery 1.7.2
cordova/phonegap 2.0.0
this application fires AJAX post calls to a remote server, something like:
$.ajax(
type: "post",
cache: false,
timeout: 30000,
url: "http://"+ username+":"+password +"#mycompany.com/mysite/and/so/on.asmx",
contentType: "text/xml",
// other params...
The application works fine in Android 2.2 and 2.3.3. So far so good.
The users have upgraded to Android 4.0.3, the main page loads fine, but ajax calls don't work anymore.
Also in the emulator of android 4.1 it's the same.
Considering nothing else has changed but the platform, what could have changed in the Webkit layer to cause the problem?
Are there known migration rules to be followed?
thank you
Quite a lot of things are more locked down in newer versions of android to improve security. Passwords included in the url are insecure, especially if you don't use https, so some browsers no longer support them.
I haven't seen anything specific to android webview, but it is definitely deprecated in google's other browser.
http://code.google.com/p/chromium/issues/detail?id=123150
Try setting the credentials in a header instead:
$.ajax({
type: "GET",
url: url,
dataType: 'json',
async: true,
data: {},
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', "Basic " + btoa(user + ':' + pass));
},
success: onSuccess,
error: onError
});
Just put <access origin="your server" subdomains="true" /> to config.xml and you are done. No need to rewrite all ajax calls ;-) Just done it with my application and its working fine on all android versions.

Phonegap + Webservice

I have a index.html with an ajax call to a webservice(ASP.NET) that works fine when i deploy it on the bigrock server(i have a domain).
$.ajax({
type: "POST",
url: "myurl/mywebservice.asmx",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert("success");
},
error: function (msg,status) {
$('#demo').html("status is "+status+" . Msg is "+msg.d.responseText);
//attribute for responsetext might be wrong here but in my application it is correct as i am using different system ryt now.
}
});
But when i used the online zipper of phonegap to make a apk for my android app from the html, css,js,web.config,few class and installed it on my device...nothing comes up. Its shows me an ajax error with no responseText.
What am i missing?
When you zip up your assets to submit to PhoneGap Build, you need to include a config.xml file and specify access policy similar to
<access origin="https://your.domain.com" />
This will instruct PhoneGap to allow communication with your server.
When your app is deployed to the device using PhoneGap, your "Home" location becomes the file-system on the local device.
This means any ajax calls are cross-domain calls which require further configuration to setup correctly.
See this question for potential answer

phonegap android ajax requests work for GET but not POST

Sending the below request in my phonegapp-ed android app works for GET but not POST.
With GET, everything works. With POST, the request goes through but the POST variables
are not coming through on the server side, and the server returns a
json response that says 'no parameters supplied.'
POST works fine from our mobile app - it is just the phonegap app where we are having an issue. What am i missing here??? Thanks in advance for any help you can provide!
I've tried changing the settings on the $.ajax call, the android manifest, everything I can think of.
Also, i'm using Android 2.2 and Phonegap 1.0
function goTeam(){
var dataString={lat:currentLocation.lat(),lng:currentLocation.lng()}; // this all works
$.ajax({
url: 'http://example.com/request/goTeam',
data: dataString,
dataType: 'json',
success:
function(b) {
if(b.status==1){ // woo hoo! it works
} else {
// the request went through but something was wrong - this is what i'm getting with POST
}
},
type: 'post', // works with GET, doesn't work with POST
error: function(jqXHR, textStatus, errorThrown){ alert("Noooo."); }
});
Are you trying cross-domain requests? Only GET requests work this way. You can use JSONP for this kind of request, but only GET works.
Phonegap does work with both GET and POST - cross-domain security issues do not apply. We had an idiosyncratic error our code that was preventing it from working. Phonegap is pretty awesome!

Categories

Resources