Платформа ionic Android не может взаимодействовать с серверной частью по протоколу http

Я тестирую связь между ионным приложением Android и серверной частью (сервер Amazon EC2).

Вот мой файл package.json:

{
  "name": "test",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "https://ionicframework.com/",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "~10.0.0",
    "@angular/core": "~10.0.0",
    "@angular/forms": "~10.0.0",
    "@angular/platform-browser": "~10.0.0",
    "@angular/platform-browser-dynamic": "~10.0.0",
    "@angular/router": "~10.0.0",
    "@capacitor/android": "^2.4.0",
    "@capacitor/core": "2.4.0",
    "@ionic-native/core": "^5.0.0",
    "@ionic-native/splash-screen": "^5.0.0",
    "@ionic-native/status-bar": "^5.0.0",
    "@ionic/angular": "^5.0.0",
    "rxjs": "~6.5.5",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1000.0",
    "@angular/cli": "~10.0.5",
    "@angular/compiler": "~10.0.0",
    "@angular/compiler-cli": "~10.0.0",
    "@angular/language-service": "~10.0.0",
    "@capacitor/cli": "2.4.0",
    "@ionic/angular-toolkit": "^2.3.0",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "codelyzer": "^6.0.0",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~3.3.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~3.9.5"
  },
  "description": "An Ionic project"
}

сервис, используемый для входа в систему:

import { Injectable } from '@angular/core';
import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError, shareReplay, tap} from 'rxjs/operators';


export interface Login {
  email: string;
  password: string;
  userType: string;
}

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class LoginService {

  constructor(private http: HttpClient) { }

  login(): Observable<any> {

    // tslint:disable-next-line:prefer-const
    let loginData: Login =  {
      email : '[email protected]',
      password : 'Test',
      userType : 'testUser'
    };

    return this.http.post('http://amazon-elastic-ip:8011/authentication-api/users/login', loginData, httpOptions).pipe(
        shareReplay(),
        tap(), catchError(this.handleError));
  }

  private handleError(error: HttpErrorResponse) {
    sessionStorage.setItem('error', JSON.stringify(error));
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
          `Backend returned code ${error.status}, ` +
          `body was: ${JSON.stringify(error.error.message)}`);
    }
    // return an observable with a user-facing error message
    return throwError(
        'Something bad happened; please try again later.');
  }
}

Home.page.ts:

import { Component, OnInit } from '@angular/core';

import {LoginService} from '../services/login.service';


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})

export class HomePage implements OnInit {

  data;
  error;

  ngOnInit() {
    console.log('Initializing HomePage');
  }

  constructor(private loginService: LoginService) {
  }


  login() {
    this.loginService.login().subscribe(data => this.data = JSON.stringify(data));
    setTimeout (() => {
      this.error = sessionStorage.getItem('error');
    }, 5000);
  }
}

и Home.html:

<ion-content [fullscreen]="true">
  <ion-header collapse="condense">
    <ion-toolbar>
      <ion-title size="large">Blank</ion-title>
    </ion-toolbar>
  </ion-header>  

  <ion-button (click)="login()">Login</ion-button>
  <h1>data</h1>
  {{data}}
  <h1>Error</h1>
  {{error}}
</ion-content>

Входящие правила для доступа к моему внутреннему серверу, порт 8011: 0.0.0.0/0 и :: / 0 (откуда угодно)

Когда я отлаживаю приложение с помощью следующей команды:

ionic capacitor run android -l --host=MY-HOST-IP

Приложение отлично работает на моем устройстве, и я могу получить токен из Backend после входа в систему.

Но когда я запускаю его, используя:

 ionic capacitor run android

У меня тайм-аут связи и следующая ошибка:

error: {isTrusted: true}
isTrusted: true
headers: {normalizedNames: {}, lazyUpdate: null, headers: {}}
headers: {}
lazyUpdate: null
normalizedNames: {}
message: "Http failure response for http://amazon-elastic-ip:8011/authentication-api/users/login: 0 Unknown Error"
name: "HttpErrorResponse"
ok: false
status: 0
statusText: "Unknown Error"
url: "http://amazon-elastic-ip:8011/authentication-api/users/login"

Кажется, что сервер не принимает связь с моим приложением, и когда он попытался получить доступ к серверу из навигатора на моем устройстве с IP-адресом порта 8011, я могу получить ответ от моего REST API. Также я попытался добавить IP-адрес своего устройства в порт 8011 входящих правил, у меня та же ошибка.

Заранее большое спасибо за вашу помощь!


person Nicolas    schedule 31.08.2020    source источник
comment
stackoverflow.com/a/62193416/1351469   -  person jcesarmobile    schedule 31.08.2020
comment
Добавив android: usesCleartextTraffic = true в тег приложения в AndroidManifest.xml, приложение будет работать нормально. Спасибо ! :)   -  person Nicolas    schedule 31.08.2020