You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 4加载图片时出现null请求问题求助

解决Angular 4中自定义Image管道+async导致的null请求问题

嘿,这个http://localhost:4200/null的无效请求我之前也碰到过,本质原因其实很明确:async管道在Observable还没吐出第一个值的时候,会返回null,而Angular的[src]绑定会把这个null直接赋值给img的src属性,浏览器就会把null解析成当前域名下的路径,于是就出现了这个莫名其妙的请求。

下面给你几个靠谱的解决办法,你可以按需选择:

方法一:延迟渲染img直到异步流有值

用ng-container先订阅异步结果,拿到有效的图片地址后再渲染img标签,从根源上避免src被设置为null:

<div class="card-avatar" (click)="openFilePicker()">
  <!-- 先拿到异步返回的图片地址 -->
  <ng-container *ngIf="(imageLink | image) | async as imageSrc">
    <img class="img pointer" 
         [ngStyle]="{'width.px': 130,'height.px': 130}" 
         *ngIf="links.avatar && imageLink" 
         [src]="imageSrc" />
  </ng-container>
  <img src="../../assets/img/default-avatar.png" class="img pointer" *ngIf="links.avatar === undefined">
</div>

这样img标签只有在拿到真实的base64地址后才会被渲染,完全不会触发null请求。

方法二:给管道的Observable添加初始空值

在管道返回的Observable上加上startWith('')操作符,让async管道一开始就拿到空字符串(而不是null),空字符串的src不会触发浏览器的请求:
首先要导入startWith操作符:

import { startWith } from 'rxjs/operators';

然后修改管道的返回逻辑:

return this.http.get(url, new RequestOptions({headers: headers, responseType: ResponseContentType.Blob}))
  .map(response => response.blob())
  .switchMap(blob => {
    return Observable.create(observer => {
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = function() {
        observer.next(reader.result);
        observer.complete(); // 别忘了调用complete,避免内存泄漏
      }
    });
  })
  .pipe(startWith('')); // 新增这一行,给Observable一个初始空值

方法三:提前校验管道的输入参数

在管道的transform方法开头,先检查传入的url是否有效,如果是空值直接返回一个空的Observable,避免无效的http请求:

transform(url: string, selfLink?: any, width?: any) {
  // 先校验url,无效直接返回空值Observable
  if (!url) {
    return Observable.of('');
  }

  // 下面是你原来的逻辑
  if (selfLink) {
    url = selfLink + url + width;
  }
  const headers = new Headers({'Authorization': 'Bearer ' + localStorage.getItem('token'), 'Content-Type': 'image/jpeg'});
  return this.http.get(url, new RequestOptions({headers: headers, responseType: ResponseContentType.Blob}))
  // ... 剩下的逻辑不变
}

另外还有两个小建议:

  1. 你现在用的是Angular 4的Http服务,其实官方已经推荐使用HttpClient了,它处理响应类型的方式更简洁,后续可以考虑升级替换。
  2. 管道里直接用localStorage.getItem('token')不太符合Angular的依赖注入规范,建议把token的获取封装成一个Auth服务,这样更便于测试和维护。

内容的提问来源于stack exchange,提问作者Alessandro Celeghin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:29:27