Hitting Web Service from JQuery Mobile app in PhoneGap - jquery-mobile

I have a JQuery Mobile app. This app needs to hit a remote web service. When I run the app from my local file system, the app loads fine. But then, when I click a button, I try to interact with the web service. When I attempt to hit the web service, I see an error in the console that says:
XMLHttpRequest cannot load https://www.mydomain.com/myService/myAction. Origin null is not allowed by Access-Control-Allow-Origin
I try to hit the service with the following code:
var vm = getParameters();
$.ajax({
url: https://www.mydomain.com/myService/myAction,
type: "POST",
data: JSON.stringify(vm),
contentType: "application/json",
success: action_Succeeded,
error: action_Failed
});
What am I doing wrong? I tried everything in this post without any luck: XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin.
My app works when I run it via Visual Studio. My hunch is that its running with in a context of a web server at that point. However, I want to deploy this via PhoneGap. Because of that, running within the context of a web server is out of the question. That's why I figured if I ran it via my local file system and everything worked, I should be good. What am I doing wrong?
Thank you so much!

Check your config.xml file (if you're using the Phonegap Build service - otherwise check the .plist file for iOS, AndroidManifest.xml for Android..), and add this line:
<access origin="*" />
If this works, then you can try to set a more restrictive access rule like:
<access origin="https://mydomain.com" subdomains="true" />
And on your server side, you'll need to return this http header:
Access-Control-Allow-Origin: *

Related

Can I use the Google Picker API in an electron app?

I'm trying to use the Google Picker API to display a picker for the user to select a file. I have this working great in a web app (in a normal browser), but when I run the same code in an electron app, I see a 400 message in the popup iframe, and get the following console errors:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://docs.google.com') does not match the recipient window's origin ('file://').
Failed to load resource: the server responded with a status of 400 ()
The core problem seems to be that the electron browser window has an origin of file://. This seems to cause two problems:
The (chromium) browser security blocks the cross-origin iframe communication
Google rejects the request as not coming from a valid origin (and you can't add file:// as an origin in the developer console)
I can't think of any way to overcome these problems, but I'm hoping that someone has an idea.
You could create an app and host it in something like following, and then point the electron BrowserWindow to the url.
https://app.yourdomain.name/gdrive/picker?token=access_token
That should work I believe.

Access-Control-Allow-Origin null value for WKWebView - Restrict to local file ONLY

I have a common web service used by a web application (internet browser access) and by a mobile app.
My iOS app loads a local html file in a WKWebView and calls this web service using javascript/ajax so as per new CORS implementation in WKWebView I must add an 'Access-Control-Allow-Origin' header to the response. I will add this header only when coming from the app and not when coming from a web browser - for security reasons.
If I set Access-Control-Allow-Origin to * everything works as expected. However I would prefer to prevent the access from anything but a local page. I have tried to set it as null and it does not work in WKWebView - but it is working if I open a local html page in Firefox that makes the ajax call.
Is is possible to achieve this in WKWebView? I have only found this https://issues.apache.org/jira/browse/CB-7348 where the person said "The only solution is, the destination server MUST return the header "Access-Control-Allow-Origin" that matches the wildcard or "null"" but it is not working on my side (iOS 10/11)

iOS11 causing CORS Issues in all mobile browsers

We were testing our website on iOS devices with iOS11, and noticed that it was breaking, as the browser would not accept responses from our API. Using the remote debugger, we were able to determine that we were getting a CORS permission error, and the response body and HTTP Headers were being stripped. This seemed to be occurring on all mobile iOS browsers (Chrome/Safari), and continued to occur even after I changed the CORS response header to a wildcard value. However, every other browser/OS/version of iOS is working perfectly. I have attached the network response from our API, the response headers for our API, and the error we are getting from the console.
Is there something about iOS11 that might be causing this, or failing that, is there any way I can get further diagnostics?
We had a similar situation with a form hosted on domain A and posting the data to an API on domain B.
The POST request from domain A contained the header "x-api-key" that is not relevant for domain B
The response to the preflight OPTIONS request to the API contained the headers
Access-Control-Allow-Origin:https://domainA
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:*
That worked fine for all browsers except those on iOS.
As we finally found out, specifying the wild card * for Access-Control-Allow-Headers
does not work for iOS browsers. In the response to the OPTIONS request you need to specify all the headers that are present in the POST request, even if some headers are not relevant for the server on domain B.
Only then will iOS send the POST request.
Changing the response header to
Access-Control-Allow-Headers:Accept,Content-Type,X-Requested-With,x-api-key
did it (even if the header x-api-key is not processed on server B)
In our case, we were able to solve the problem by adding additional http header information when making an OPTIONS preflight request from our API. It appears that Safari does not like wild cards entries in CORS requests, and additionally, needs every header specified in the Access-Control-Allow-Header value, even 'standard' ones that would not be necessary in other browsers. By adding the following headers to all preflight requests, we were able to get X-Domain requests between our site and our api working again.
<!-- headers for preflight CORS response-->
<add key="Access-Control-Allow-Origin" value="<exact name of site>" />
<add key="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, DELETE" />
<add key="Access-Control-Allow-Credentials" value="true" />
<add key="Access-Control-Allow-Headers" value="Accept,Origin,Content-Type,X-LS-CORS-Template,X-LS-Auth-Token,X-LS-Auth-User-Token,Content-Type,X-LS-Sync-Result,X-LS-Sequence,token" />
iOS 11 has introduced some new tracking protection which block some sites/URL
You can disable this in Settings -> Safari -> Prevent Cross-Site Tracking.
Maybe that is your problem ?
I have the same problem, this works - but I would like a way about without our users have to do this.
source: https://www.macrumors.com/how-to/safari-ios-11-tracking-prevention/
I faced the same issue.
The problem in my case was that nginx was not letting the file upload go because the body was too large and nginx did not let that request pass to the application and just killed the connection. I changed the client_body_max_size 10M and it just worked. Look into your nginx error log!
Took me about whole day to figure out.

redirectURL: for Phonegap iOS Facebook login on Node+Passport.js

Building an iOS app with Phonegap and Passport.js I point to
http://www.example.com/auth/facebook?redirectURL=...
to login. The server runs on http://www.example.com.
The ... is my question! What do I fill there?
My files are served locally, something like file:///var/...
If I redirect to window.location.href, I get JSON output.
If I redirect to http://www.example.com it works, but then I'm simply browsing the online web-app, instead of the local files (and no Cordova-plugin-support anymore)..
Please advice!

Phonegap iOS ajax request never completes

I have a phonegap app which connects to a web service and authenticates using http basic authentication. It is built using phonegap build and targets Android and iOS.
On a login view, an ajax request fires against the remote server to check if credentials are correct, then if so, logs the user in to the main application.
This completes successfully in ripple emulator on desktop pc and when also when deployed onto an Android device.
However, when the app is deployed onto an iOS device (ipod touch) the authentication request simply does not ever complete. Using phonegap remote debugger I can see that the ajax request starts but never completes. It is always in a pending state. I use jquery ajax success, error and complete handlers for the request, but none of them are ever hit so I don't get the chance to see any error messages returned from the server. The request never seems to complete.
I have tried making ajax requests to other remote web sites to test that my app can communicate and they succeed, so it doesn't seem as though I have white-listing issues.
Any ideas of what the issue could be?
Please read the update to this answer at bottom.
Original answer
I have found what the issue is and managed to get basic authentication working.
The issue was that the web server was expecting basic authentication details to be preemptively sent with the request.
To do this use the 'headers' property of jquery ajax as shown below:
$.ajax
({
type: "GET",
url: "https://webserver/authenticate",
headers: {
"Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
}
})
.done(function(){
alert('Authenticated!')
})
.fail(function(){
alert('Error!')
});
See related answer:
https://stackoverflow.com/a/11960692/1463497
Update
I found in the end that there is no reliable way of using basic authentication in a web view in iOS. I.e everything is fine if correct credentials are entered but when they are not and the 401 challenge response comes along, iOS web view can't seem to handle it.
In the end, the web service authentication was implemented by simply passing 'username' and 'password' parameters as part of the url:
url: "https://webserver/authenticate?username=abc&password=123"
This is the only consistent way I found of getting authentication to work across iOS and Android in a web view (by getting rid of basic authentication altogether). This of course meant updating the web service itself to accept authentication in this way.

Resources