首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态创建和嵌入角中的数据URL

动态创建和嵌入角中的数据URL
EN

Stack Overflow用户
提问于 2022-05-17 07:35:06
回答 1查看 816关注 0票数 0

在我的角度应用中,我有以下不变的基本条件:

  1. 应用程序动态地从外部URL加载ZIP文件。
  2. 在这个ZIP文件中,有一个要提取的

文件。这个HTML文件可能包含带有data:image/jpeg;base64,...-like源的图像(但没有外部链接)。

我成功地用JSZip等实现了1和2。因此,我们可以假设,现在有一个String变量htmlFileContent。在另一个空角选项卡中显示特定条件下的iFrame也不是问题,我设法做到了。为了实现第3点的其余部分,我看到了两种不同的方法:

使用div:

使用htmlFileContent作为div元素的innerHTML,如下所示:

代码语言:javascript
运行
复制
<div [innerHtml]="{{ htmlFileContent }}"></div>

这确实有效,但有一些令人难以置信的副作用,例如,“内部”title标题也在浏览器中呈现。因此,我可以尝试将htmlFileContent解析为DOM,并删除不需要的树元素。这也许是一个可行的解决方案,但不知怎么的,我对此并不满意。

此外,HTML还包含一些文件中的锚链接(<a href="#topOfPage">样式),这些链接也将不再工作,需要进行更正。

使用 iFrame

我非常了解iFrame用法的丑陋和贬义,尽管如此,在我看来,这似乎是解决我的问题的适当方法。所以我会用:

代码语言:javascript
运行
复制
<iframe [src]="fileUrl" class="fullscreenIFrame"></iframe>

这里出现了一个问题:可以设置fileUrl="data:text/html;charset=utf-8,"+ htmlFileContent。但是,角质会(正确地)抱怨:ERROR Error: NG0904: unsafe value used in a resource URL context (see https://g.co/ng/security#xss)和任何东西都不会显示。因此,目前我正在使用来自DomSanitizer@angular/platform-browser进行类似的尝试

代码语言:javascript
运行
复制
this.filedata = this.sanitizer.bypassSecurityTrustHtml(htmlFileContent);
this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl("data:text/html;charset=utf-8,"+ this.filedata) ;

这在一定程度上是可行的:我在输出中呈现了一个警告SafeValue must use [property]=binding:,并在第一个src="data:..."图像出现的地方剪切了“内部”src="data:..."

我被困在这里了。当然,我的iFrame只能有一个src,我不能连接fileUrl (然后将其缩短为data:text/html;charset=utf-8,内容)和fileData,因为其中一个是SafeResourceUrl,另一个是SafeHtml对象。

以下是我的问题所在:

https://stackblitz.com/edit/angular-ivy-uzpcsy?file=src/app/app.component.ts

(有趣的是,图像在这里呈现.无论如何,SafeValue警告仍然存在。)

对于如何处理这一特殊要求,您有什么建议吗?div-approach还会是更好的吗?任何帮助都是非常感谢的--非常感谢!

EN

Stack Overflow用户

回答已采纳

发布于 2022-05-24 06:08:40

由于我没有收到或找到另一种可能性,所以我实现它的方式--仅供参考:

代码语言:javascript
运行
复制
import { ActivatedRoute, Router, UrlSegment } from '@angular/router';
import { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';

export class MyComponent implements OnInit {
  
  filedata: SafeHtml = 'Loading...';
  currentUrl: string = '';  

  constructor(
    private activatedRoute: ActivatedRoute,
    private sanitizer: DomSanitizer,
  ) {}

  ngOnInit(): void {
    // Use the Angular possibilities to retrieve to complete current URL
    this.activatedRoute.url.subscribe(url => {
      this.currentUrl = '';
      url.forEach(urlElement => {
        this.currentUrl += urlElement + '/';
      });
      this.currentUrl = this.currentUrl.substring(0, this.currentUrl.length - 1);
    });
    this.loadFileData();
  }

  loadFileData(): void {
    // This is the function where the ZIP file is downloaded and the file
    // content is extracted. As it is not part of the question or the
    // answer, I will not post it here.
    // Let's just assume, the file content is now stored in "response".
    this.filedata = 
    this.sanitizer.bypassSecurityTrustHtml(this.correctFileData(response));
  }

  // Receives the file content response as first parameter,
  // removes the unwanted tags and corrects the anchor links.
  private correctFileData(response: string): string {
    let el = document.createElement('html');
    el.innerHTML = response;

    // Remove all "head" tags including their inner elements
    // (Of course, the should be only one head tag, but you never know...)
    let headElements = el.getElementsByTagName('head');

    for (let i = 0; i < headElements.length; i++) {
      el.removeChild(headElements[i]);
    }

    // Correct all anchor links: Prepend the current URL
    // So http://my.address.com/#anchor would become
    // http://my.address.com/myApp/myRoute/mySubRoute#anchor
    // for example
    let links = el.getElementsByTagName('a');
    for (let i = 0; i < links.length; i++) {
      let link = links[i];
      if (link.href.indexOf('#') != -1) {
        console.log(link.href + ' --> ' + this.currentUrl + 
          link.href.substring(link.href.indexOf('#')));
        link.href = this.currentUrl + link.href.substring(link.href.indexOf('#'));
      }
    }

    return el.outerHTML;
  }

在组件的HTML中,我只使用:

代码语言:javascript
运行
复制
<div [innerHTML]="filedata"></div>

可能还有其他更好的解决方案,但这个解决方案对我的用例非常有效。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72269891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档