Javascript Angular 2 - 检查图像 url 是否有效或损坏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36429903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:03:30  来源:igfitidea点击:

Angular 2 - Check if image url is valid or broken

javascriptangular

提问by Jakob Svenningsson

I am fetching a large number of image URLs from an API and display them in a angular 2 web application. Some of the URLs are broken and i want to replace them with a default picture that is stored locally on my webserver. Does anyone have a suggestion how to test the urls and in the case of status code 404 replace the broken image?

我正在从 API 获取大量图像 URL 并将它们显示在 angular 2 Web 应用程序中。一些 URL 已损坏,我想用本地存储在我的网络服务器上的默认图片替换它们。有没有人建议如何测试网址并在状态代码 404 的情况下替换损坏的图像?

Thanks!

谢谢!

回答by Günter Z?chbauer

Listen to the errorevent of the image element:

监听error图像元素的事件:

<img [src]="someUrl" (error)="updateUrl($event)">

where updateUrl(event) { ... }assigns a new value to this.someUrl.

whereupdateUrl(event) { ... }为 分配一个新值this.someUrl

Plunker example

Plunker 示例

If you want to check in code only you can use the method explained in Checking if image does exists using javascript

如果您只想签入代码,则可以使用使用 javascript 检查图像是否存在中说明的方法

@Directive({
  selector: 'img[default]',
  host: {
    '(error)':'updateUrl()',
    '[src]':'src'
   }
})
class DefaultImage {
  @Input() src:string;
  @Input() default:string;

  updateUrl() {
    this.src = this.default;
  }
}

Directive Plunker example

指令 Plunker 示例

回答by micronyks

You can use onErrorevent this way to handle invalid urlor broken url.

您可以通过onError这种方式使用事件来处理invalid urlbroken url

<img [src]="invalidPath" onError="this.src='images/angular.png'"/> 

This way you can directly assign img path to src with onError event

这样你就可以通过 onError 事件直接将 img 路径分配给 src

回答by sergamers

My example on angular 4

我的角度为 4 的例子

<img [src]="img" (error)="img.src = errorImg" #img>
  1. Where img - path to image;
  2. error - error emmit
  3. errorImg - path to default img
  4. #img - link to img object
  1. 其中 img - 图像路径;
  2. 错误 - 错误发出
  3. errorImg - 默认 img 的路径
  4. #img - 链接到 img 对象

回答by doneDone

I found a very simple solution that worked for me. This doesn't check for 404's however I had objects that possibly had and .image attribute. I know this isn't the answer to his question but hopefully it helps some one out there.

我找到了一个对我有用的非常简单的解决方案。这不会检查 404,但是我有可能具有 .image 属性的对象。我知道这不是他问题的答案,但希望它可以帮助那里的人。

<img class="list-thumb-img" [attr.src]="item.image?.url ? item.image.url : 'assets/img/140-100.png'">

回答by robert king

I use a base64 loading spinner:

我使用 base64 加载微调器:

<img [src]="photoContainer.photo.url | secure" onError="this.src='data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI0MHB4IiBoZWlnaHQ9IjQwcHgiIHZpZXdCb3g9IjAgMCA0MCA0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7IiB4PSIwcHgiIHk9IjBweCI+CiAgICA8ZGVmcz4KICAgICAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWwogICAgICAgICAgICBALXdlYmtpdC1rZXlmcmFtZXMgc3BpbiB7CiAgICAgICAgICAgICAgZnJvbSB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoLTM1OWRlZykKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQGtleWZyYW1lcyBzcGluIHsKICAgICAgICAgICAgICBmcm9tIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDBkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHRvIHsKICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC0zNTlkZWcpCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN2ZyB7CiAgICAgICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7CiAgICAgICAgICAgICAgICAtd2Via2l0LWFuaW1hdGlvbjogc3BpbiAxLjVzIGxpbmVhciBpbmZpbml0ZTsKICAgICAgICAgICAgICAgIC13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuOwogICAgICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDEuNXMgbGluZWFyIGluZmluaXRlOwogICAgICAgICAgICB9CiAgICAgICAgXV0+PC9zdHlsZT4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJvdXRlciI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwwQzIyLjIwNTgsMCAyMy45OTM5LDEuNzg4MTMgMjMuOTkzOSwzLjk5MzlDMjMuOTkzOSw2LjE5OTY4IDIyLjIwNTgsNy45ODc4MSAyMCw3Ljk4NzgxQzE3Ljc5NDIsNy45ODc4MSAxNi4wMDYxLDYuMTk5NjggMTYuMDA2MSwzLjk5MzlDMTYuMDA2MSwxLjc4ODEzIDE3Ljc5NDIsMCAyMCwwWiIgc3R5bGU9ImZpbGw6YmxhY2s7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNNS44NTc4Niw1Ljg1Nzg2QzcuNDE3NTgsNC4yOTgxNSA5Ljk0NjM4LDQuMjk4MTUgMTEuNTA2MSw1Ljg1Nzg2QzEzLjA2NTgsNy40MTc1OCAxMy4wNjU4LDkuOTQ2MzggMTEuNTA2MSwxMS41MDYxQzkuOTQ2MzgsMTMuMDY1OCA3LjQxNzU4LDEzLjA2NTggNS44NTc4NiwxMS41MDYxQzQuMjk4MTUsOS45NDYzOCA0LjI5ODE1LDcuNDE3NTggNS44NTc4Niw1Ljg1Nzg2WiIgc3R5bGU9ImZpbGw6cmdiKDIxMCwyMTAsMjEwKTsiLz4KICAgICAgICA8L2c+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCwzMi4wMTIyQzIyLjIwNTgsMzIuMDEyMiAyMy45OTM5LDMzLjgwMDMgMjMuOTkzOSwzNi4wMDYxQzIzLjk5MzksMzguMjExOSAyMi4yMDU4LDQwIDIwLDQwQzE3Ljc5NDIsNDAgMTYuMDA2MSwzOC4yMTE5IDE2LjAwNjEsMzYuMDA2MUMxNi4wMDYxLDMzLjgwMDMgMTcuNzk0MiwzMi4wMTIyIDIwLDMyLjAxMjJaIiBzdHlsZT0iZmlsbDpyZ2IoMTMwLDEzMCwxMzApOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksMjguNDkzOUMzMC4wNTM2LDI2LjkzNDIgMzIuNTgyNCwyNi45MzQyIDM0LjE0MjEsMjguNDkzOUMzNS43MDE5LDMwLjA1MzYgMzUuNzAxOSwzMi41ODI0IDM0LjE0MjEsMzQuMTQyMUMzMi41ODI0LDM1LjcwMTkgMzAuMDUzNiwzNS43MDE5IDI4LjQ5MzksMzQuMTQyMUMyNi45MzQyLDMyLjU4MjQgMjYuOTM0MiwzMC4wNTM2IDI4LjQ5MzksMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxMDEsMTAxLDEwMSk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMy45OTM5LDE2LjAwNjFDNi4xOTk2OCwxNi4wMDYxIDcuOTg3ODEsMTcuNzk0MiA3Ljk4NzgxLDIwQzcuOTg3ODEsMjIuMjA1OCA2LjE5OTY4LDIzLjk5MzkgMy45OTM5LDIzLjk5MzlDMS43ODgxMywyMy45OTM5IDAsMjIuMjA1OCAwLDIwQzAsMTcuNzk0MiAxLjc4ODEzLDE2LjAwNjEgMy45OTM5LDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoMTg3LDE4NywxODcpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTUuODU3ODYsMjguNDkzOUM3LjQxNzU4LDI2LjkzNDIgOS45NDYzOCwyNi45MzQyIDExLjUwNjEsMjguNDkzOUMxMy4wNjU4LDMwLjA1MzYgMTMuMDY1OCwzMi41ODI0IDExLjUwNjEsMzQuMTQyMUM5Ljk0NjM4LDM1LjcwMTkgNy40MTc1OCwzNS43MDE5IDUuODU3ODYsMzQuMTQyMUM0LjI5ODE1LDMyLjU4MjQgNC4yOTgxNSwzMC4wNTM2IDUuODU3ODYsMjguNDkzOVoiIHN0eWxlPSJmaWxsOnJnYigxNjQsMTY0LDE2NCk7Ii8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8cGF0aCBkPSJNMzYuMDA2MSwxNi4wMDYxQzM4LjIxMTksMTYuMDA2MSA0MCwxNy43OTQyIDQwLDIwQzQwLDIyLjIwNTggMzguMjExOSwyMy45OTM5IDM2LjAwNjEsMjMuOTkzOUMzMy44MDAzLDIzLjk5MzkgMzIuMDEyMiwyMi4yMDU4IDMyLjAxMjIsMjBDMzIuMDEyMiwxNy43OTQyIDMzLjgwMDMsMTYuMDA2MSAzNi4wMDYxLDE2LjAwNjFaIiBzdHlsZT0iZmlsbDpyZ2IoNzQsNzQsNzQpOyIvPgogICAgICAgIDwvZz4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggZD0iTTI4LjQ5MzksNS44NTc4NkMzMC4wNTM2LDQuMjk4MTUgMzIuNTgyNCw0LjI5ODE1IDM0LjE0MjEsNS44NTc4NkMzNS43MDE5LDcuNDE3NTggMzUuNzAxOSw5Ljk0NjM4IDM0LjE0MjEsMTEuNTA2MUMzMi41ODI0LDEzLjA2NTggMzAuMDUzNiwxMy4wNjU4IDI4LjQ5MzksMTEuNTA2MUMyNi45MzQyLDkuOTQ2MzggMjYuOTM0Miw3LjQxNzU4IDI4LjQ5MzksNS44NTc4NloiIHN0eWxlPSJmaWxsOnJnYig1MCw1MCw1MCk7Ii8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4K'">

回答by Ing Guillermo Malagón

If you want to change an image that is not loading or the source is broken... Angular 8, just have to change the src of this target for a default asset:

如果要更改未加载的图像或源已损坏... Angular 8,只需更改此目标的默认资源的 src:

  • Component HTML

    <... [src]="person.pictureUrl" (error)="pictNotLoading($event)" >

  • Component TS

    pictNotLoading(event) { event.target.src = 'assets/nopicture.png'; }

  • 组件 HTML

    <... [src]="person.pictureUrl" (error)="pictNotLoading($event)" >

  • 组件 TS

    pictNotLoading(event) { event.target.src = 'assets/nopicture.png'; }

回答by Shashank Agrawal

A perfect Angular 8 directive:

一个完美的 Angular 8 指令:

import {AfterViewInit, Directive, ElementRef, Input} from '@angular/core';

@Directive({
    selector: '[appImage]'
})
export class ImageDirective implements AfterViewInit {

    @Input() src;

    constructor(private imageRef: ElementRef) {
    }

    ngAfterViewInit(): void {
        const img = new Image();
        img.onload = () => {
            this.setImage(this.src);
        };

        img.onerror = () => {
            // Set a placeholder image 
            this.setImage('assets/placeholder.png');
        };

        img.src = this.src;
    }

    private setImage(src: string) {
        this.imageRef.nativeElement.setAttribute('src', src);
    }
}

Now, HTML will be:

现在,HTML 将是:

<img [src]="'/some/valid-image.png'" appImage>

回答by born2net

this is my solution for fallback on multi images. we basically detach the ChangeDetector once we resolve the image so we can reduce CPU on vm check cycles once image is resolved.

这是我对多图像回退的解决方案。一旦我们解析了图像,我们基本上就会分离 ChangeDetector,这样一旦图像被解析,我们就可以减少虚拟机检查周期上的 CPU。

import {Component, ChangeDetectionStrategy, ChangeDetectorRef} from 'angular2/core';
import {AppStore} from "angular2-redux-util/dist/index";



@Component({
    selector: 'logoCompany',
    changeDetection: ChangeDetectionStrategy.Default,
    template: `
            <div style="padding-top: 7px" > 
              <span style="color: gainsboro; font-family: Roboto">{{getBusinessInfo('companyName')}}</span>
              <!--<img style="width: 35px" class="img-circle" src="http://galaxy.example.me/Resources/Resellers/{{getBusinessInfo('businessId')}}/{{getBusinessInfo('fileName')}}" />-->
              <img style="width: 35px" class="img-circle" [src]="getImageUrl()" (load)="onImageLoaded()" (error)="onImageError()" />
            </div>
    `
})

export class LogoCompany {

    constructor(private cdr:ChangeDetectorRef) {    
    }
    private imageRetries:number = 0;
    private unsub;


    private detach() {
        this.cdr.detach();
    }

    private getImageUrl() {          
        var url = '';
        switch (this.imageRetries){
            case 0: {
                url = 'http://galaxy.example.me/Resources/Resellers/' + this.getBusinessInfo('businessId') + '/Logo.jpg'
                break;
            }
            case 1: {
                url = 'http://galaxy.example.me/Resources/Resellers/' + this.getBusinessInfo('businessId') + '/Logo.png'
                break;
            }
            default: {
                url = 'assets/person.png'
                break;
            }

        }
        return url;
    }

    private onImageLoaded() {
        this.detach();
    }

    private onImageError() {
        this.imageRetries++;
    }

    private getBusinessInfo(field):string {
          return '12345';
    }





}

回答by Chirag Jain

You can simply use a ternary operator for this use case. I am assuming that you are getting the responses from a remote server

对于此用例,您可以简单地使用三元运算符。我假设您正在从远程服务器获得响应

<img src="{{ res.image ? res.image : onErrorFunction() }}"

If you don't want to have the image from server write the path in single quotes ''.

如果您不想让来自服务器的图像用单引号 '' 写路径。

Here if the link is broken then it will go to onErrorFunction if it isn't broken the res.image will be loaded.

在这里,如果链接断开,那么它将转到 onErrorFunction 如果它没有断开,则将加载 res.image。