BASE64转图片Angular 2

52

我正在尝试使用Angular 2显示从远程服务器获取的图像。

在我的组件中,我有一个对象,它是一个“university_info”对象,它是我的模型。

export class myClass
{
    university_info : university_info;
}
myFunction()
{
    this.university_info = new university_info(responseFromServer[image])
}

export class university_info
{
    imageBase64 : string
    constructor(image : string)
    {
        this.imageBase64 = image
    }
}

一切都很好。我得到了base64的图片,但是当我尝试以这种方式在HTML中展示它时:

  <img [src]="'data:image/jpg;base64,'+university_info.imageBase64" />
这是我得到的内容:

这是我得到的:

在此输入图片描述

在此输入图片描述

在此输入图片描述

7个回答

105

我觉得这个帖子缺乏具体的例子,这让我有些困难:

导入DomSanitizer:

import { DomSanitizer } from '@angular/platform-browser';

在构造函数中定义:

constructor(private _sanitizer: DomSanitizer) { }

使用 trustResourceUrl 函数对要作为图像资源传递的 Base64 字符串进行清理:

this.imagePath = this._sanitizer.bypassSecurityTrustResourceUrl('data:image/jpg;base64,' 
                 + toReturnImage.base64string);

绑定到html:

<img [src]="imagePath">

1
耶耶耶:这应该是答案:它像魔法一样运行:)谢谢;) - Deunz
1
对我非常有帮助。感谢您的整理。 - Hodglem
1
很好的回答,只是缺少导入信息.. import { DomSanitizer } from '@angular/platform-browser'; - Ricardo Huertas
比其他答案好很多。 - Javi Marzán
如果我有多种类型的图像,比如png、jpeg、jpg,data:image/jpg;base64,对所有这些类型都适用吗? - M Nouman

45

解决方法:只需像这样在您的图像标签中使用'data:image/jpg;base64'即可

<img src="{{'data:image/jpg;base64,' + imagePath}}" />

这是最简单的解决方案。第一次尝试就成功了。 - Nathan
是的,可能是最简单的方法。 - Buminda
1
不错的解决方案。但是关于XSS安全风险呢?! - Leebeedev
1
这对我没用,我仍然得到了相同的错误。使用 Angular 11。 - luca.vercelli
@Rahul Jograna- 先生,我已经使用了上述代码,但在HTML的src属性中显示为对象-对象,您能告诉我如何修复它吗? - Kapil Soni

15
你可以尝试使用_sanitizer.bypassSecurityTrustUrl告诉Angular src的值是安全的。请参考Angular中的这个类:
class DomSanitizationService {
    sanitize(context: SecurityContext, value: any) : string
    bypassSecurityTrustHtml(value: string) : SafeHtml
    bypassSecurityTrustStyle(value: string) : SafeStyle
    bypassSecurityTrustScript(value: string) : SafeScript
    bypassSecurityTrustUrl(value: string) : SafeUrl
    bypassSecurityTrustResourceUrl(value: string) : SafeResourceUrl
}

以下是一个安全的HTML示例:

export class AppComponent  {

    private _htmlProperty: string = '<input type="text" name="name">';

    public get htmlProperty() : SafeHtml {
       return this._sanitizer.bypassSecurityTrustHtml(this._htmlProperty);
    }

    constructor(private _sanitizer: DomSanitizationService){}
}

谢谢,它运行得很好。这篇文章还更详细地解释了DomSanitizationService的工作原理。https://medium.com/@NetanelBasal/angular-2-security-the-domsanitizer-service-2202c83bd90#.88dtia8xl - Ricardo Huertas

12
请查看以下示例,了解如何在Angular 2/4中上传图像并显示。实际的base64字符串已转储到调试器控制台中,当然可以存储在数据库中等等。
import { Component, OnInit } from '@angular/core';
// Base 64 IMage display issues with unsafe image
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-test',
  template: `
            <h1>Test 001 </h1>

          <div class="form-group">
            <label>Image</label>
            <input type="file" class="form-control" accept="application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint,
            text/plain, application/pdf, image/*" (change)="changeListener($event)">
          </div>

          <img *ngIf="base64Image" [src]="domSanitizer.bypassSecurityTrustUrl(base64Image)" />
    `,
  styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {

  private base64Image: string;

  constructor(private domSanitizer: DomSanitizer) { }

  ngOnInit() {
  }

  changeListener($event): void {
    this.readThis($event.target);
  }

  readThis(inputValue: any): void {
    var file: File = inputValue.files[0];
    var myReader: FileReader = new FileReader();

    myReader.onloadend = (e) => {
      this.base64Image = myReader.result;
      console.log(this.base64Image);
    }
    myReader.readAsDataURL(file);
  }

}

9
请确保university_info.imageBase64字符串类型,然后您的代码就可以正常运行。

演示:http://plnkr.co/edit/pI35tx9gXZFO1sXj9Obm?p=preview
import {Component,ViewChild,Renderer,ElementRef,ContentChildren} from '@angular/core';

@Component({
  selector: 'my-app',

  template:   `
  <img [src]="'data:image/jpg;base64,'+imagePath"/> 
  `

})
export class App {
  imagePath:string="iVBORw0KG...";
}

3
我想提出一个备选方案,建立在@gatapia提供的方案之上。
所提出的解决方案是使用@ViewChild装饰器标签(请参见此处的文档 https://angular.io/docs/ts/latest/api/core/index/ViewChild-decorator.html),以检索组件内的元素引用,并直接设置值,如下面的代码片段所示。需要注意的是,通过ViewChild引用的元素应该使用#绑定到本地变量中,如下面的代码片段所示。
另外,正如ElementRef文档所解释的那样,直接使用ElementRef仍然存在XSS风险,这种风险也存在于使用DomSanitizer时。
@Component({
  template: `
    <div>
      <img #imgRef> // Note that the #imgRef reference is required to be identified by Angular
    </div>
  `,
})
export class MyComponent implements OnInit {
  src:string;
  @ViewChild('imgRef') img:ElementRef;

  constructor() {
    // In your case, this will be resolved from the server
    this.src = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=';
  }

  ngOnInit() {
    // Sets the value of the element
    this.img.nativeElement.src = this.src;
  }
}

以下plunkr提供了上述内容的工作代码片段https://plnkr.co/edit/JXf25Pv8LqrFLhrw2Eum?p=preview

这是一个完美的反应,没有太多麻烦,我唯一需要调整的就是在ngAfterViewChecked上等待信息到位。 - Fabian Rios
重要的是要知道,Angular的DOM安全性有非常好的原因。考虑到大多数UI工程师实际上并不像他们应该了解XSS或其他类型的攻击(这不是一种轻蔑,只是事实),我们不应该试图绕过他们内置的保护措施。 为此,请使用Angular提供的dom sanitizer。这里提供的示例是一个直接的、明显的安全漏洞,可以通过免费使用Angular库提供的工具(而且,具有更少的代码)轻松缓解。 - dudewad

2

这个问题在谷歌搜索排名很高,所以我想把我的发现放在这里。使用数据绑定来设置图像的[src]属性可能会在一些旧的移动设备上出现问题,特别是性能方面。因此,如果您在使用清理器+绑定方法时遇到性能问题,您将不得不直接使用DOM来设置src属性:

constructor(private el: ElementRef) {}

...

public imageChanged(base64: string) {
  const im: HTMLImageElement = this.el.nativeElement.querySelector('#imgid'); 
  im.src = data;
}

这可能看起来不太美观,但速度非常快。

如此快速,动作优美。 - Karl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接