javascript - 嵌入式 booking.com 无法正确显示
问题描述
我正在尝试将 booking.com 嵌入式小部件添加到项目中。在对主页的第一次请求时,它工作正常,您可以看到用于订购的地图和预订小部件。但是,当您切换视图(不离开页面或关闭选项卡)并按返回返回主页面时,它会变成一个链接,并且嵌入的地图小部件不会显示。加载主页后,我可以看到预订请求并返回一个 JS 脚本。在这个脚本之后,很多脚本/html 像谷歌地图被调用,但它只发生在主页上,并且一次,其他时候仍然看到脚本被调用,但没有别的不。
import { Component, Inject, OnInit, Renderer2 } from '@angular/core';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'jhi-booking-frame',
templateUrl: './booking-frame.component.html',
styles: []
})
export class BookingFrameComponent implements OnInit {
name = 'Angular';
constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document: Document) {}
ngOnInit(): void {
const s = this._renderer2.createElement('script');
s.type = 'text/javascript';
s.async = false;
s.src = '//aff.bstatic.com/static/affiliate_base/js/flexiproduct.js' + '?v=' + +new Date();
const elementsByTagNameElement = this._document.getElementsByTagName('head')[0];
this._renderer2.appendChild(elementsByTagNameElement.parentElement, s);
}
}
<ins class="bookingaff" data-aid="0000" data-target_aid="0000" data-prod="map" data-width="100%" data-height="590" data-lang="ualng" data-dest_id="0" data-dest_type="landmark" data-latitude="35.6894875" data-longitude="139.6917064" data-mwhsb="0" data-checkin="2019-05-20" data-checkout="2019-05-21">
<!-- Anything inside will go away once widget is loaded. -->
<a href="//www.booking.com?aid=0000">Booking.com</a>
</ins>
我已经尝试过诸如 afterInitView、onInit 等的 Angular 钩子。它应该像这个例子一样https://stackblitz.com/edit/angular-8564pe?file=src%2Fapp%2Fapp.component.html但它只显示一个预订链接。
解决方案
我不得不自己去看,好像预订的小部件脚本在 Angular 的生命周期中表现不佳。在组件被销毁并重新初始化后,您的<ins>
标签不会与脚本一起评估。我可以想到两种解决方案,
1-防止组件被破坏。为此,您可以使用 RouteReuseStrategy。从理论上讲,这样渲染的 iframe 应该持续存在。
2-这是最简单的解决方案。只需使用渲染的<iframe>
而不是<ins>
. 如果您希望您的初始日期、longtitute 等是动态的,您需要做的就是相应地创建 www.booking.com/flexiproduct.html 调用的查询参数并将其绑定到 iframe 的 src。
<iframe src="//www.booking.com/flexiproduct.html?product=map&w=100%25&h=590&lang=tr-TR&aid=0000&target_aid=0000&ss_id=0&ss_type=landmark&checkin=2019-05-20&checkout=2019-05-21&fid=1561904636317&latitude=35.6894875&longitude=139.6917064&mwhsb=0&"
scrolling="no"
style="order:none;padding:0;margin:0;overflow:hidden;width:100%;height:590" marginheight="0" marginwidth="0" allowtransparency="true" id="booking_widget__0000__1561904636317"
data-responsive="true" width="100%" height="590" frameborder="0"></iframe>
您需要使用消毒剂将其标记为安全。
@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
用法:
<iframe [src]="bookingUrl| safe"></iframe>
https://www.linkedin.com/pulse/working-iframe-angular-thiago-adriano/
附加信息无论来源是什么,都需要谨慎对待 iframe 的来源。对于不受信任的来源,不建议绕过清理。
推荐阅读
- php - 当一部分为空时,Symfony 删除 ManyToMany 相关对象?
- java - 用于循环的 Java REST API
- r - RStudio 服务器无法连接到服务
- azure-ad-b2c - 为来宾用户受邀者从 Azure AD 提取报告
- ios13 - 更新到 Xcode 11 后无法启动应用程序问题
- powerapps - 如何修复powerapps中的“必填”字段?
- c# - 在一定数量的行之后拆分datagridview
- reactjs - React 中的服务器端搜索
- python - 如何在python中加载具有多个“无扩展文件”的数据集?
- asp.net - 我想在按钮单击时打开引导模式 .net webform