Ionic http fail(response 0) - android

We are building an app which requires an API request.
On front end we are using Ionic with Angular. When we tried to send a request to backend we get this error.
It works when we are trying on desktop in browser.
{
"headers":{
"normalizedNames":{
},
"lazyUpdate":null,
"headers":{
}
},
"status":0,
"statusText":"Unknown Error",
"url":"http://server_ip:3000/path/useCode/1234",
"ok":false,
"name":"HttpErrorResponse",
"message":"Http failure response for http://server_ip:3000/path/useCode/1234: 0 Unknown Error",
"error":{
"isTrusted":true
}
}
This is how we send a request.
import { HttpClient, HttpHeaders } from '#angular/common/http';
public sendCodeGET() {
this.httpClient.get(`http://server_ip:3000/path/useCode/${this.code.trim()}`).subscribe(
res => {
this.response = JSON.stringify(res);
},
err => {
this.response = JSON.stringify(err);
this.presentToast(err.error['message']);
}
);
}
We are using NodeJS v10.15.3 where we set CORS header presented below.
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept, Authorization");
res.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS, DELETE");
res.setHeader("Access-Control-Expose-Headers","Content-Length,Content-Range");
if (req.method === 'OPTIONS') {
res.setHeader('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
return res.status(200).json({});
}
next();
});
config.cml
<access origin="*" />
<allow-navigation href="*" />
<allow-intent href="*" />
index.html
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
We have also tried:
- other API (https://coinmarketcap.com/api)
- POST and GET requests

I faced the same issue, but i sorted it as below. Follow these steps
Open [yourProject]/android/app/src/main/AndroidManifest.xml
2.Add this line there android:usesCleartextTraffic="true"
3.Add this line to config.xml file
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:usesCleartextTraffic="true" />
</edit-config>

Some things I would suggest trying;
Download a CORS plugin that can allow you to bypass blocked headers
If you're using ionic I am assuming that this if for a hybrid app. Make use of ionic HTTP. You could get better results.
Check out Ionic's official docs for some help https://ionicframework.com/docs/troubleshooting/cors

Related

axios requests throw "Network Error" on Android (Cordova container)

I have wrapped a Vue app into a Cordova container and deployed on Android via Android Studio. Each request that goes out to my server is failing with the message Error: Network Error.
This is not an issue in browser or iOs.
I have researched this issue and tried various solutions:
I have installed the cordova-plugin-whitelist plugin and configured as described in the documentation
I have set permissions in the AndroidManifest.xml file:
<edit-file mode="merge" parent="/manifest/uses-permission" target="AndroidManifest.xml">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</edit-file>
I have setup a "Content-Security-Policy" tag in meta:
<meta data-n-head="1" http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src *; style-src * 'unsafe-inline';">
I have changed my server address from localhost:3000 to my server's IP address as instructed in this answer: Network error with axios and android emulator - I also tried to run it via a local-tunnel to have a "real" API URL - same issue
As instructed in the thread above, I have also added headers:
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json"
Still Error: Network Error.
I am almost sure this has to do with permissions but there is nothing more I could configure to make it work.
I am testing this on Android 10.0+ device using Cordova 10.
Axios on 0.20.0.
I found a solution for my problem. It looks like Android is not allowing requests to http by default, as stated in this thread: Internet permission not working in oreo and pie
Changing the localtunnel to https solved the issue for me.

Href not working despite CSP and <allow-intent>

I have made an app using PhoneGap (so I am writing in HTML, JavaScript and CSS) and in this app I've written multiple "href" functions such as these:
<a href="mailto:marcel.loman#apt-alu-products.com">
marcel.loman#apt-alu-products.com </a><br />
Website: www.apt-alu-products.com</p>
I have added some "Content-security-policy lines in the "head" part of all of my HTML documents to ensure the fact it would work if I run the apk on android. This CSP looks lik this:
<meta http-equiv="Content-Security-Policy"
content="default-src *;
style-src * 'self' 'unsafe-inline' 'unsafe-eval';
script-src * 'self' 'unsafe-inline' 'unsafe-eval';">
On top of that I've added the following lines in my config.xml file in between the "widget" part:
<allow-intent href="http://*/" />
<allow-intent href="https://*/*" />
<allow-intent href="mailto:*" />
<allow-navigation href="*" />
<allow-intent href="*" />
<access origin="*" />
(I know these lines aren't recommended due to security reasons, but these were my last resort)
Despite of al these lines the links still don't work when I build an APK out of it and run it on my Android phone.
There are lots of articles on the internet about this subject, but none of the ones i read were able to tackle my problem.
Adding these links directly into the app's HTML without the inappbrowser plugin will not work. The http link will actually load the content into your Webview, replacing your app code.
I assume you want the mailto link to launch the default mail client and the http link to open in the system browser? Assuming this, do the following:
First, add the inappbrowser plugin to your project:
cordova plugin add cordova-plugin-inappbrowser
Then add some code to use the inappbrowser plugin to open the link with window.open rather than the default behaviour of opening the link within the Webview.(The following uses jQuery):
$(document).on('click', 'a[href^=http], a[href^=mailto]', function(e){
e.preventDefault(); // prevent Webview from following link
window.open($(this).attr('href'), '_system'); // Open with inappbrowser
});

HTTPS blocked for Ionic build --release android apk

Debug apk works fine, which rules out the usual suspects, but when I build, sign, install the release version, no https $http API calls can be made by angular (http to the same endpoint, which I permitted for debugging, works).
cordova whitelist is installed
ionic plugin add cordova-plugin-whitelist
manifest.xml contains the correct directives
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Ionic config.xml contains the correct directives
<access origin="*"/>
<allow-navigation href="*" />
My index.html declares a permissive Content-Security-Policy:
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
I also checked my intermediate certificate chain using two different online SSL checkers--they are fine.
I'm totally stumped. Any ideas?
Re-apply SSL certs taking special care to include intermediary certs.
Despite https://cryptoreport.websecurity.symantec.com/checker/ and three other SSL checkers saying my SSL certs were fine, just to be safe I reset and configured my AWS Elastic Load Balancer SSL settings ensuring we I had included the (says optional, but not optional) intermediate cert, and the problem went away after that.
Modify this function in SystemWebViewClient.java found in
platforms\android\CordovaLib\src\org\apache\cordova
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
final String packageName = this.cordova.getActivity().getPackageName();
final PackageManager pm = this.cordova.getActivity().getPackageManager();
ApplicationInfo appInfo;
try {
appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// debug = true
handler.proceed();
return;
} else {
// debug = false
// THIS IS WHAT YOU NEED TO CHANGE:
// 1. COMMENT THIS LINE
// super.onReceivedSslError(view, handler, error);
// 2. ADD THESE TWO LINES
// ---->
handler.proceed();
return;
// <----
}
} catch (NameNotFoundException e) {
// When it doubt, lock it out!
super.onReceivedSslError(view, handler, error);
}
}
This will ignore if there is any SSL error occured on third party signed self generated certificates.
read in detail here

Apache Cordova: Failed to load resource: the server responded with a status of 404 (Not Found)

When I run my application either in the Android emulator or on my Android device, I get he following error on all AJAX requests:
Failed to load resource: the server responded with a status of 404 (Not Found)
I have tried all the following steps to solve this problem, but it persists.
Installed the whitelist plugin to the project using npm.
Added <plugin name="cordova-plugin-whitelist" version="1" /> to
config.xml.
Added <uses-permission android:name="android.permission.INTERNET" />
to platforms\android\AndroidManifest.xml.
Added <meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline';"> and <meta http-equiv="X-XSS-Protection" content="0"> to the <head> of www/index.html file.
Added <access origin="*" />, <allow-navigation href="*" /> and
<allow-intent href="*" /> to the config.xml file.
Regardless I still get the same errors. Any ideas?
The project compiles fine. I'm on Windows 7, using Cordova 5.4.0, Android 5.1.1
Removing the whole Android part of the application with:
cordova platform remove android
and adding it again with:
cordova platform add android
solved the problem, which is still a mystery to me.
Perhaps there was something wrong left from the earlier versions of Cordova that wasn't getting on well with the current Cordova version.
I think the problem's with your Content Security Policy meta tag - try adding * to the default-src to open up Ajax requests to anywhere. You could also add a connect-src clause specifically for Ajax requests and list the hosts and protocols you want to be able to access. For example:
<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://myhost.mydomain.com">
Would allow Ajax requests to http://myhost.mydomain.com
I wrote a blog post addressing this topic that you may find helpful, it can be read here.
Update Android
cordova platform update android#5.1.1
I had the problem for me connect to a php page on my server and I made an update to android

Phonegap Cross-domain AJAX POST Request not working on Android

Cross-domain AJAX POST request works perfectly fine on web browsers including browsers on mobile phones, but doesn't work for native applications built using Phonegap
I have created a login form that users have to enter their login credentials, then they are verified by the server that is hosted on heroku and returns json {"success":true} if valid credentials are entered.
My Ajax script:
$.ajax({
type: "POST",
url: "http://domain.com/public/auth/app-login",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "json",
data: {identity: <username from form>, password: <password from form>},
crossDomain: true,
cache: false,
success: function(data) {
obj = JSON.parse(data);
if (obj && obj.success === true) {
window.location.href = 'home.html';
}
},
error: function(e) {
alert('Error: ' + e.message);
}
});
Steps taken to resolve this issue:
Domain whitelisting - config.xml
<access origin="http://domain.com/public/auth/app-login" />
<access origin="*" />
Telling jQuery to allow cross-domain
$.support.cors = true;
OR
jQuery.support.cors = true;
Disable caching cache: false
Any help is appreciated.
Ok. If index.html in local then you can call ajax any hosts, not need enable CORS in client or server. You remove:
$.support.cors = true; OR jQuery.support.cors = true;
And:
<access origin="http://domain.com/public/auth/app-login" />
It redundant, only use:
<access origin="*" />
You need check and add in AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
Add more permission if your app required. Finally, call ajax inside $(document).ready():
$.ajax({
type: "POST",
url: "http://domain.com/public/auth/app-login",
dataType: "json",
data: {identity: <username from form>, password: <password from form>},
success: function(data) {
obj = JSON.parse(data);
if (obj && obj.success === true) {
window.location.href = 'home.html';
}
},
error: function(e) {
alert('Error: ' + e.message);
}
});
If you are looking to resolve this issue then you may wish to make sure that the plugin is being properly included into the build process.
RESOURCE: \app\config.xml
<widget>
.... [lots of stuff] ....
<gap:plugin name="com.indigoway.cordova.whitelist.whitelistplugin" />
<access origin="http://*" />
....
</widget>
You may also wish to specify a version as that is recommended, and I do not specify one above. A good way to test if the plugin is included is to use the free cloud account provided at, https://build.phonegap.com/apps. If you build your project there you can check the plugins tab and make sure that the whitelist plugin is included.
I have read that you should only need this in the HEAD element of your HTML page, but I found as of the date of this post that I still needed to include the plugin.
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
If the plugin is not loaded you might get a "Not Found" error when using the $.ajax method for jQuery for the error string.
Some of the information on the Internet will tell you that the whitelist information is placed into the /www/res/ folder, but this appears to be outdated information. You may also find that <plugin... is used in some examples, but it appears that this may be an obsolete way?
Also, you may need:
RESOURCE: \app\config.xml
<widget>
...
<feature name="http://api.phonegap.com/1.0/network"/>
...
</widget>
use
JSON.stringify(data: {identity: <username from form>, password: <password from form>})
instead of
data: {identity: <username from form>, password: <password from form>}
I got success message when i changed my code like this.
Some time there is issue in your domain. In my case I resolved it by putting following code in my .htaccess file
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>

Categories

Resources