I'm developing a Cordova app for android, and I have a strange issue about jquery ajax calls: the debug build have no problem, while in the release one each ajax call fails with an error. If I run on device using USB everything is fine. If I compile the app in debug mode, copy and install it on the device, everything is fine.
If I compile the app in release mode and sign it for release using jarsigner and zipalign, and copy and install it on the device, the same ajax call fail with readyState 0, responseText empty, status 0 and statusText "error".
I spent a week searching and trying all the similar problems found on stackoverflow and google, but nothing changed.
This thread subject is similar, but my SSL certificate seems to be ok and there's no other solutions provided:
Ajax calls fail when running Android Cordova app in Release mode
Cordova version is 6.5 (but I had the issue in the 6.4 too).
This is the ajax call in the app:
glang = window.localStorage.getItem('glang');
show_loader();
$.support.cors=true;
$.ajax({
url: "https://app.laureatedesign.com/wp-content/plugins/designnews/ajax_langs.php",
data: "act=aj_app_lng_lst&lang="+glang+"&xend=x",
type: "POST",
dataType: "json",
timeout: 10000,
success: function(results) {
if (results["TYPE"]=="OK") {
$('#main').html(results["CONTENT"]);
$('#main').imagesLoaded( { },
function() {
show_content();
}
);
}
if (results["TYPE"]=="ERR") {
show_error();
}
},
error: function(XMLHttpRequest, status) {
console.log(status);
switch(status) {
default:
show_error();
break;
case "timeout":
show_error();
break;
}
}
});
By all means the ajax file ajax_langs.php on server can be simplified as follows:
<?php
$res = array("TYPE"=>"OK", "CONTENT"=>"Test");
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
echo json_encode($res);
?>
This is my config.xml:
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.naba.designnews" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>APPTITLE</name>
<description>
DESCRIPTION
</description>
<author email="EMAIL" href="WEBSITE">
AUTHOR
</author>
<content src="index.html" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />
<plugin name="InAppBrowser" value="CDVInAppBrowser" />
<allow-navigation href="*" />
<allow-navigation href="*://*youtube.com" />
<access origin="*" />
<access origin=".*" />
<access origin="*.pushwoosh.com" />
<access origin="http://*" />
<access origin="https://*" />
<access origin="https://laureatedesign.com" subdomains="true" />
<allow-intent href="http://*" />
<allow-intent href="https://*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="windows-target-version" value="10.0" />
<preference name="StatusBarOverlaysWebView" value="false" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
I added the whitelist-plugin.
In index.html file I have this meta:
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src * 'self' 'unsafe-inline'; script-src * 'self' 'unsafe-inline'; connect-src * https: http:">
I tried also to remove android platform and add it again. No changes.
As I said in debug mode everything is fine and all ajax calls returns successfully. In order to publish the app on Google Play I am proceeding signing and creating the package as follows:
1) cordova build android --release
2) jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore "PATH-TO-APP/APP.keystore" "PATH-TO-APP/platforms/android/build/outputs/apk/android-release-unsigned.apk" designnews
3) zipalign -v 4 "PATH-TO-APP/platforms/android/build/outputs/apk/android-release-unsigned.apk" "PATH-TO-APP/platforms/android/build/outputs/apk/AppTitle.apk"
I'm aware this is a cross-domain call involving CORS and all this stuff. But why the debug version is ok while the release one is not?
Please help, thanks in advance.
i know its´s a 3 years old question but after a deep searching a found the solution and a i want to share it.
I had the same issue you report, an the solution was so simple;
1º - You need to run "cordova prepare android" to get java binaries.
2º - Open the code that output that command on Android Studio, navigate on folder manifests/AndroidManifest.xml
3º - There is a called "application", you only need to add android:usesCleartextTraffic="true"
4º - Build and sign your app, now it should run ajax without any trouble!
Related
Im trying to create a angular app using Alfresco adf components (https://github.com/Alfresco/alfresco-ng2-components) and need to have a mobile app too, so i decide use cordova to generate apk.
I follow the following tutorial (https://medium.com/#nacojohn/convert-your-angular-project-to-mobile-app-using-cordova-f0384a7711a6) to generate my apk.
All seems to works fine, apk was generated and install in BlueStack, until i have to make login in my app.
Origin is not allowed by access-control-allow-origin
I know that i need to have a whitelist policy for navigating the application webview
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.hello" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>HelloWorld</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<allow-navigation href="*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<plugin name="cordova-plugin-device" spec="^2.0.2" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.3" />
<engine name="android" spec="^7.0.0" />
<engine name="ios" spec="^4.5.4" />
</widget>
index.html
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"
My angular web app have a dev-server proxy to fix the CORS problem
proxy.conf.json
{
"/alfresco": {
"target": "server-url",
"secure": false,
"changeOrigin": true
},
"/activiti-app": {
"target": "another-server-url",
"secure": false,
"changeOrigin": true
}
}
I dont know what i need to do more. Have i made something wrong? need to do something more?
Thanks
I think you should enable CORS in the Alfresco server, you can achieve that either by:
Including this dependency in you Alfresco extension.
Or by enabling CORS directly in the Tomcat server, full details can be found in the Tomcat documentation.
you have to enable CORS for details see Getting Started with Alfresco Application Development Framework
My problem was lack of configuration in app.config.json.
Instead of
"ecmHost": "http://{hostname}{:port}",
"bpmHost": "http://{hostname}{:port}"
I just need to set ecmHost and bpmHost to my servers and all works fine.
Thanks for helping guys
I've got an node.js (express) webapp running on localhost:3000. I am now trying to develop a mobile app using cordova.
I've got a route defined in my express app 'localhost:3000/tweets' which when called gets some tweets using twitter API and send them back as json object. Everythinngs works very fine using web app however I am struggling to make the same ajax call from a mobile app. To allow requests from other hosts I've added this to my edxpress app.js:
EDIT: i use cors middleware now:
app.use(cors());
In my cordova app:
meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="<id...>" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>appname</name>
<description>
A twitter search app.
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<access origin="*" />
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<engine name="android" spec="^6.2.3" />
<plugin name="cordova-plugin-camera" spec="^2.4.1" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.2" />
</widget>
In the index.html file i link 'querySender.js' file at the bottom of body:
<script type="text/javascript" src="js/querySender.js"></script>
And finally, content of 'querySedner.js'
$(document).ready(function(){
$('#btn_send').on('click', function(){
console.log("app is now sending query!");
$.ajax({
type: 'POST',
url: 'http://127.0.0.1:3000/tweets',
data: {name:"test_name",lastname:"last_name"},
dataType:'json',
success: function(dataR){
var date = new Date();
console.log("POST success recorded at: ",date.getTime());
if (!dataR){
console.log("No Data received");
}else{
console.log("DataR: ",dataR);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log("Status: " + textStatus+" error:"+ errorThrown);
},
timeout:5000
});
});
});
using WebStrom IDE i tried to run index.html in chrome (it runs it on localhost:63342) the request succeeds and data is delivered as expected.
however is emulate the app using android emulator when i press the button i get:
POST http://127.0.0.1:3000/tweets net::ERR_CONNECTION_REFUSED -- jquery-3.2.1.min.js:4
Basically. I'm running my node.js(express) server locally and would like to make ajax calls to it from cordova app on android emulator. What did I get wrong?
Okay, after frustrating hours of research I finally found that localhost or 127.0.0.1 refers just to emulator it self but not the computer it runs on. To fix this problem I just had to send the request to my computers (on which node.js server runs on) local ip. In my case local ip was 192.168.0.2 so I changed:
http://127.0.0.1:3000/tweets
to:
http://192.168.0.2:3000/tweets
And it seems to work now.
I have Phonegap build app for android made with html + javascript (jquery). Yesterday it was working perfectly. Today ajax calls does't perform anymore. Sample code:
$(document).ready(function(){
setTimeout(function(){
$.ajax({
url: urlPrefix + "/xxxxx",
dataType: "jsonp",
jsonpCallback: "indexCallback"
});
alert('Ajax praejo');
},2000);
});
function indexCallback(response) {
alert('callback prasideda');
}
Alert after ajax call is showing, but alert in indexCallback function not appearing. Ajax calls external back-end server. I have made loging of calls in back-end server, but no call appears.
I have tried to make timeout before ajax is calling, but no result.
I white listed all possible domains in config.xml file:
<plugin name="cordova-plugin-whitelist" version="1" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<allow-navigation href="http://*/*" />
<allow-navigation href="https://*/*" />
<allow-navigation href="data:*" />
Everything works fine when i load index.html (ajax calls to external back-end) file into desktop browser.
Any ideas ?
I had a similiar problem with my app on android devices. After days of research i found following blog post. The certificate from our cert authority(top 4 ) was part of a bug in google webview. After updating the webview and chrome on the devices everything worked again.
Test again with the deviceready listener.
http://docs.phonegap.com/en/1.0.0/phonegap_events_events.md.html
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
setTimeout(function(){
$.ajax({
url: urlPrefix + "/xxxxx",
dataType: "jsonp",
jsonpCallback: "indexCallback"
});
alert('Ajax praejo');
},2000);
}
function indexCallback(response) {
alert('callback prasideda');
}
Check your contents meta data.
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
I have a cordova android app for showing news from a JSON web service
the ajax request work on web browser but not work on android when i create the .apk file
the link of the app https://github.com/Adib12/technologia
My config file
<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Technologia</name>
<description>
Suivre les actualités des nouvelles technologies
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Aouadi Adib ( AdibDev )
</author>
<content src="index.html" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
I need help
From the Github link you posted, it looks like you are trying to connect to a localhost URL. This won't work when running on a device, so you'll need to change that to the name of the resource you're connecting to, or its IP address (best to use DNS name).
Additionally I notice you don't have a Content-Security-Policy meta tag in the head section of your index.html - you will need one of these for Cordova 5 and higher... this specifies what resources your app can connect to. Assuming your service that you want to make an Ajax request to is running at http://myserver.mydomain.com, your CSP meta tag would need to look something like this:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src http://myserver.mydomain.com">
I wrote a blog post that covers set up of Content Security Policy for Android and iOS here.
Please change localhost to a valid server name in your www/js/script.js, specifically here:
$.ajax({
type: "POST",
url: "http://localhost/sv/connect.php",
data: formData,
cache: false,
dataType: 'JSON',
success: onSucces,
error: onError
});
and add a Content Security Policy meta tag to your www/index.html in the head section.
I have been testing my app using ionic serve while developing and everything is working fine. I am now trying to export the apk using ionic build android, then storing the file 'android-debug.apk' on my web server and downloading it via a phone's browser and installing it to test it in the real world.
The app installs OK, but won't let me make any $http requests. I have installed the plugin cordova-plugin-whitelist, and also added the following to my config.xml file:
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="*" />
<allow-navigation href="*" />
<allow-intent href="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
As well as that, I have added this into my main index.html file:
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
Can someone tell me why the requests are still failing please?
I have tested on 2 different servers, both have CORS enabled and this has been verified using Postman.
Thanks for any help
Edit:
My $http request looks like this:
$http.get('http://url.com/request').then(function(res) {
console.log('success');
console.log(res);
}, function(res) {
console.log('error');
console.log(res);
});
After enabling remote chrome debugging, I get an error alert, following by an object which has:
data: null,
status: 0,
statusText: ""
Looks like I needed to add:
<uses-permission android:name="android.permission.INTERNET" />
into platforms/android/AndroidManifest.xml. Working OK now!