Предполагая, что вы реализовали HttpIntercepter для добавления заголовка, вот решение, которое действительно работает (в Angular 4):
import { Pipe, PipeTransform } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Pipe({
name: 'secure'
})
export class SecurePipe implements PipeTransform {
constructor(private http: HttpClient) { }
transform(url: string) {
return new Observable<string>((observer) => {
// This is a tiny blank image
observer.next('data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
// The next and error callbacks from the observer
const {next, error} = observer;
this.http.get(url, {responseType: 'blob'}).subscribe(response => {
const reader = new FileReader();
reader.readAsDataURL(response);
reader.onloadend = function() {
observer.next(reader.result);
};
});
return {unsubscribe() { }};
});
}
}
Вы используете это так:
<img [src]="'/api/image/42' | secure | async" />
Предыдущие решения имели серьезные недостатки. Я не гарантирую, что это идеально, но на самом деле это проверено и работает для меня.
Вы не можете вернуть наблюдаемое, полученное с http.get! Я не знаю, почему предыдущие решения предполагают, что вы можете. Наблюдаемый для http.get указывает, когда данные извлекаются с сервера. Но после этого необходимо выполнить еще один асинхронный процесс: вызов reader.readAsDataURL. Поэтому вам нужно создать Observable, который вы будете вызывать после завершения этого процесса.
Кроме того, если вы не поместите что-то в изображение сразу, браузер все равно попытается загрузить изображение с помощью HTTP, и вы получите сообщение об ошибке в консоли JavaScript. Это причина первого вызова Observer.next, который помещает пустое крошечное изображение GIF.
Проблема с этим подходом заключается в том, что если изображение используется более одного раза, оно будет загружаться каждый раз. Даже если браузер кеширует, вы каждый раз выполняете преобразование в base64. Я создал кеш, в котором хранится изображение, чтобы последующие запросы не требовались после первого.
person
Charles
schedule
05.03.2018