【问题标题】:iFrame validation http get SRCiFrame 验证 http 获取 SRC
【发布时间】:2017-08-15 12:39:07
【问题描述】:

正如我之前所读到的,我无法使用 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 是一个注入服务,我从中获取跨域属性的标头选项。

iFrame 已加载,我从 URL 收到 200 OK,但随后显示错误消息并更改了 src。

我尝试在我的组件中打印错误状态或消息 (console.log('error status', error.status);) 但我总是得到一个未定义的。知道为什么吗?

【问题讨论】:

    标签: angular iframe rxjs


    【解决方案1】:

    您应该使用 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}`);
          }
        }
      });
    

    【讨论】:

    • 谢谢!我会尝试一下,虽然我收到“找不到模块”错误。我想我必须先安装软件包。
    • 不幸的是,我认为我不能使用 HttpErrorResponse,因为我需要 @angular/common 4.3 并且我使用的是 4.0.3 版本,这是我唯一可以使用的版本。
    【解决方案2】:

    所以,最后我无法使用 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 值,这将不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多