HTTP 在网络中有效但在实际 android 设备中无效(IONIC 移动开发)
HTTP works in web but not working in actual android device ( IONIC mobile development )
Problem: my ngfor works perfecty on running web, but when ı emulate my app on real device, its just not working. ı looked all over
the internet for solution but couldnt find, just as a close one(thats
what ı think), some says this is ngZone issue, and ı dont have any
idea what is it.
我的服务
getMenuObject(): Observable<any> {
return this.http
.post("xxxxxxx.xxxxxxxxx.xxxxxxxxx.xxxxxxxxxxx",{ HotelId:25, GroupId:9 });
}
我的.ts
data: Array<any>=[]
ngOnInit(){
this.httpService.getMenuObject().toPromise().then(x=>{
this.data = x;
console.log(this.data)
if(x.IsGroup==true){
this.splashScreen.hide();
} else{
this.router.navigate(['folder/Inbox']);
}
});
}
我的html:
<ion-card *ngFor="let otel of data.MobileHotelDefinitions" style="margin: 40px 0;border-radius: 0;">
<ion-card-header style="padding: 0;">
<ion-img (click)="goToHotel()" [src]="otel.MobileApplicationDefinition.GroupImageUrl"></ion-img>
<div class="otelName">
<div style="flex: 1;">{{otel.Name}}</div>
<div style="color: goldenrod;">★★★★★</div>
</div>
</ion-card-header>
<ion-card-content>
Keep close to Nature's heart... and break clear away, once in awhile,
and climb a mountain or spend a week in the woods. Wash your spirit clean.
</ion-card-content>
</ion-card>
我的控制台:
我在网络浏览器上的应用程序(ionic serve --o):
我在真实 android 设备上的应用程序(华为 android 9):
data
变量不是数组。它里面的MobileHotelDefinitions
属性就是数组。所以最好将它的类型定义为 any
而不是 Array
.
- 是否有将 HTTP observable 转换为 promise 的特定需求?尝试直接使用observable。
- 在使用属性之前在模板中包含
*ngIf
检查。
- 注意模板中 safe navigation operator
?.
的使用。它会在尝试访问它的子属性之前检查父 属性 是否已定义。
控制器
data: any; // <-- `any` here
ngOnInit() {
this.httpService.getMenuObject().subscribe(
response => {
this.data = response;
console.log(this.data);
if (response.IsGroup == true) {
this.splashScreen.hide();
} else {
this.router.navigate(['folder/Inbox']);
}
},
error => {
// always good practice to handle HTTP errors
}
);
}
模板
<ng-container *ngIf="data"> <!-- check here -->
<ion-card *ngFor="let otel of data.MobileHotelDefinitions" style="margin: 40px 0;border-radius: 0;">
<ion-card-header style="padding: 0;">
<ion-img (click)="goToHotel()" [src]="otel?.MobileApplicationDefinition?.GroupImageUrl"></ion-img>
<div class="otelName">
<div style="flex: 1;">{{otel?.Name}}</div>
<div style="color: goldenrod;">★★★★★</div>
</div>
</ion-card-header>
<ion-card-content>
Keep close to Nature's heart... and break clear away, once in awhile,
and climb a mountain or spend a week in the woods. Wash your spirit clean.
</ion-card-content>
</ion-card>
</ng-container>
如果问题仍然存在,则变量更新在 Angular 区域之外。尝试将 NgZone.run()
函数中的调用包装到 运行 Angular 区域内的语句。
import { Component, NgZone, OnInit } from '@angular/core';
export class AppComponent implements OnInit {
data: any;
constructor(private zone:NgZone) { }
ngOnInit() {
this.httpService.getMenuObject().subscribe(
response => {
this.zone.run(() => this.data = response); // <-- assign the value within Angular zone and trigger change detection
console.log(this.data)
if (response.IsGroup == true) {
this.splashScreen.hide();
} else {
this.router.navigate(['folder/Inbox']);
}
},
error => {
// always good practice to handle HTTP errors
}
);
}
我的问题是我试图使用 httpClient(angular 一个),但是在移动设备上你需要离子 http,所以有 2 个 http:
- 从'@ionic-native/http/ngx'导入{HTTP}; //对于移动http
要求你必须使用这个 (you can install it from here)
- 从“@angular/common/http”导入{HttpClient}; //对于浏览器
开发你必须使用这个。
并且很难为移动设备实施正确的 http 方式,为了帮助您,我在这里留下了一个示例移动 http 请求。 (以防止出现几个 http 错误)
我的Service.ts
constructor(private http:HTTP, private httpWEB: HttpClient) {
this.http.setHeader('*', 'Access-Control-Allow-Origin' , '*');
this.http.setHeader('*', 'Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
this.http.setHeader('*', 'Accept','application/json');
this.http.setHeader('*', 'content-type','application/json');
this.http.setDataSerializer('json');
}
post(url:string,body:any):Promise<any>{
return new Promise((resolve, reject) => {
this.http.setDataSerializer('json');
this.http.post(url, body, {}).then(res =>{
resolve(JSON.parse(res.data));
})
.catch(err =>{
reject(err);
});
});
}
在 Config.xlm 中更新此部分以防止 http 请求的 clearTextTraffic 错误
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:networkSecurityConfig="@xml/network_security_config" />
<application android:usesCleartextTraffic="true" />
</edit-config>
同时更新你的network_securty_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">testapi.xxx.com</domain>
</domain-config>
</network-security-config>
Problem: my ngfor works perfecty on running web, but when ı emulate my app on real device, its just not working. ı looked all over the internet for solution but couldnt find, just as a close one(thats what ı think), some says this is ngZone issue, and ı dont have any idea what is it.
我的服务
getMenuObject(): Observable<any> {
return this.http
.post("xxxxxxx.xxxxxxxxx.xxxxxxxxx.xxxxxxxxxxx",{ HotelId:25, GroupId:9 });
}
我的.ts
data: Array<any>=[]
ngOnInit(){
this.httpService.getMenuObject().toPromise().then(x=>{
this.data = x;
console.log(this.data)
if(x.IsGroup==true){
this.splashScreen.hide();
} else{
this.router.navigate(['folder/Inbox']);
}
});
}
我的html:
<ion-card *ngFor="let otel of data.MobileHotelDefinitions" style="margin: 40px 0;border-radius: 0;">
<ion-card-header style="padding: 0;">
<ion-img (click)="goToHotel()" [src]="otel.MobileApplicationDefinition.GroupImageUrl"></ion-img>
<div class="otelName">
<div style="flex: 1;">{{otel.Name}}</div>
<div style="color: goldenrod;">★★★★★</div>
</div>
</ion-card-header>
<ion-card-content>
Keep close to Nature's heart... and break clear away, once in awhile,
and climb a mountain or spend a week in the woods. Wash your spirit clean.
</ion-card-content>
</ion-card>
我的控制台:
我在网络浏览器上的应用程序(ionic serve --o):
我在真实 android 设备上的应用程序(华为 android 9):
data
变量不是数组。它里面的MobileHotelDefinitions
属性就是数组。所以最好将它的类型定义为any
而不是Array
.- 是否有将 HTTP observable 转换为 promise 的特定需求?尝试直接使用observable。
- 在使用属性之前在模板中包含
*ngIf
检查。 - 注意模板中 safe navigation operator
?.
的使用。它会在尝试访问它的子属性之前检查父 属性 是否已定义。
控制器
data: any; // <-- `any` here
ngOnInit() {
this.httpService.getMenuObject().subscribe(
response => {
this.data = response;
console.log(this.data);
if (response.IsGroup == true) {
this.splashScreen.hide();
} else {
this.router.navigate(['folder/Inbox']);
}
},
error => {
// always good practice to handle HTTP errors
}
);
}
模板
<ng-container *ngIf="data"> <!-- check here -->
<ion-card *ngFor="let otel of data.MobileHotelDefinitions" style="margin: 40px 0;border-radius: 0;">
<ion-card-header style="padding: 0;">
<ion-img (click)="goToHotel()" [src]="otel?.MobileApplicationDefinition?.GroupImageUrl"></ion-img>
<div class="otelName">
<div style="flex: 1;">{{otel?.Name}}</div>
<div style="color: goldenrod;">★★★★★</div>
</div>
</ion-card-header>
<ion-card-content>
Keep close to Nature's heart... and break clear away, once in awhile,
and climb a mountain or spend a week in the woods. Wash your spirit clean.
</ion-card-content>
</ion-card>
</ng-container>
如果问题仍然存在,则变量更新在 Angular 区域之外。尝试将 NgZone.run()
函数中的调用包装到 运行 Angular 区域内的语句。
import { Component, NgZone, OnInit } from '@angular/core';
export class AppComponent implements OnInit {
data: any;
constructor(private zone:NgZone) { }
ngOnInit() {
this.httpService.getMenuObject().subscribe(
response => {
this.zone.run(() => this.data = response); // <-- assign the value within Angular zone and trigger change detection
console.log(this.data)
if (response.IsGroup == true) {
this.splashScreen.hide();
} else {
this.router.navigate(['folder/Inbox']);
}
},
error => {
// always good practice to handle HTTP errors
}
);
}
我的问题是我试图使用 httpClient(angular 一个),但是在移动设备上你需要离子 http,所以有 2 个 http:
- 从'@ionic-native/http/ngx'导入{HTTP}; //对于移动http 要求你必须使用这个 (you can install it from here)
- 从“@angular/common/http”导入{HttpClient}; //对于浏览器 开发你必须使用这个。
并且很难为移动设备实施正确的 http 方式,为了帮助您,我在这里留下了一个示例移动 http 请求。 (以防止出现几个 http 错误)
我的Service.ts
constructor(private http:HTTP, private httpWEB: HttpClient) {
this.http.setHeader('*', 'Access-Control-Allow-Origin' , '*');
this.http.setHeader('*', 'Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
this.http.setHeader('*', 'Accept','application/json');
this.http.setHeader('*', 'content-type','application/json');
this.http.setDataSerializer('json');
}
post(url:string,body:any):Promise<any>{
return new Promise((resolve, reject) => {
this.http.setDataSerializer('json');
this.http.post(url, body, {}).then(res =>{
resolve(JSON.parse(res.data));
})
.catch(err =>{
reject(err);
});
});
}
在 Config.xlm 中更新此部分以防止 http 请求的 clearTextTraffic 错误
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:networkSecurityConfig="@xml/network_security_config" />
<application android:usesCleartextTraffic="true" />
</edit-config>
同时更新你的network_securty_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">testapi.xxx.com</domain>
</domain-config>
</network-security-config>