正如我之前读过的,我无法使用onError或onLoad函数验证iFrame是否已加载,未加载或仍在Chrome中加载,因此我决定使用简单的http get测试为iFrame提供的SRC的URL。
我开始使用特定的URL加载iFrame,并使用http get同时检查URL。如果http get返回200 OK,则表示iFrame已正确加载,因此我隐藏了一条错误消息(this.iFrameStatus = false;)。如果http返回错误,那么我应该更改iFrame URL并显示错误消息(this.iFrameStatus = true;)。
组件
export class StatusComponent implements OnInit {
public iFrameUrl: any;
public iFrame: any;
public iFrameStatus: boolean = false;
public counter: number = 0;
public errorMessage: any;
//Assign URL to iFrame in constructor
constructor(private _sanitizer: DomSanitizer, public _element: ElementRef, private _verificationService: VerificationService) {
this.iFrameUrl = this._sanitizer.bypassSecurityTrustResourceUrl(constant.Url);
setTimeout(() => {
this.iFrameStatusVerification();
}, 3000);
}
//Verify if iFrame is correctly loaded
ngAfterViewInit() {
this.iFrame = this._element.nativeElement.querySelector('.iFrame');
}
iFrameStatusVerification() {
this._verificationService.getAppStatus().subscribe(
data => {
console.log('success', data);
this.iFrameStatus = false;
this.iFrameUrl = this._sanitizer.bypassSecurityTrustResourceUrl(constant.Url);
},
error => {
error => this.errorMessage = <any>error
console.log('error', error);
console.log('error status', error.status);
console.log('error ok', error.ok);
this.iFrameStatus = true;
//this.iFrame.src = constant.emptyIFrame;
this.iFrameUrl = this._sanitizer.bypassSecurityTrustResourceUrl(constant.emptyIFrame);
}
);
}
ngOnInit() {
}
}
服务
@Injectable()
export class VerificationService {
//External App iFrame Verification
getAppStatus(): Observable<String[]> {
let url = constant.localServer + constant.Url;
console.log(url);
return this.http.get(url, this._requestOptions)
.timeout(5000)
.map(res => { let body = res.json(); return body; })
.catch((err: any): any => {
this.handleError(err, 'Error app not found ');
//return Observable.of(err);
});
}
handleError(err: any, message: string) {
let errMsg = (err.message) ? err.message :
err.status ? `${err.status} - ${err.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.of(err);
}
}
this._requestOptionsare是一个注入服务,我从中获取Cross Origin属性的头选项。
iFrame已加载,我从URL收到200 OK,但随后显示错误消息并更改了src。
我尝试在我的组件中打印错误状态或消息(console.log('error status',error.status);)但我总是得到一个未定义的。知道为什么吗?
答案 0 :(得分:0)
您应该使用 HttpErrorResponse 来检查外部API可能出现的故障。
如何使用它?
import { HttpErrorResponse } from '@angular/common/http';
http
.get<ItemsResponse>('api url')
.subscribe(
data => {...},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('An error occurred:', err.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
}
}
});
答案 1 :(得分:0)
所以,最后我不能使用HttpErrorResponse,但我深入挖掘了我的http get,这是一个明显的错误。
当设置iFrame的变量URL时,它可以工作,我得到200 OK,另一方面当我执行http get时,我必须在我的标题中指定我想接受的数据类型。在这种情况下是一个带有HTML的文档,因此设置请求选项“Accept”:“text / html,...”就可以了。
iFrame验证
getAppStatus(): Observable<String[]> {
let url = constant.Url;
let headers = new Headers({ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' });
let options = new RequestOptions({ headers: headers });
return this.http.get(url, options)
.timeout(2000)
.catch(this.handleErrorMessage);
}
第二个错误是使用map运算符,通常你可以使用 .map(this.extractData)
extractData(res:Response){
let body = res.json();
console.log('Body', body);
return body || [];
}
如果您尝试从HTML文档中提取json值,则无效。