Kat*_*eva 7 html bearer-token angular
我的任务是使用auth标头进行异步图像请求.我有像这样的图像路径:
<img src="{{file.src}}"/>
Run Code Online (Sandbox Code Playgroud)
我需要为此类请求添加承载令牌到标头.页面包含许多图像,因此ajax请求不适合.不知道该怎么做.
假设你已经实现了一个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() { }};
});
}
}
Run Code Online (Sandbox Code Playgroud)
你这样使用它:
<img [src]="'/api/image/42' | secure | async" />
Run Code Online (Sandbox Code Playgroud)
以前的解决方案存在严重缺陷.我不保证这是完美的,但它实际上已经过测试并且适合我.
你无法返回从http.get获得的observable!我不知道为什么以前的解决方案假设你可以.http.get的observable指示何时从服务器检索数据.但是,还有另一个异步过程必须在此之后完成:对reader.readAsDataURL的调用.因此,您需要创建一个Observable,您将在该过程完成后接下来调用它.
此外,如果您没有立即在图像中添加某些内容,浏览器仍会尝试使用HTTP加载图像,并且您在JavaScript控制台中出现错误.这就是第一个观察到一个空的微小GIF图像的observer.next调用的原因.
这种方法的一个问题是,如果图像被多次使用,它将每次加载每个图像.即使浏览器缓存,您也会每次都转换为base64.我创建了一个存储图像的缓存,以便在第一个之后不需要将来的查询.
现在,无法仅通过 html 中的标签进行 Authorized 调用,浏览器没有为此提供 API,因此您必须发出 XHR 请求。这是一个解决方法:通过 XHR 获取图像,将其转换为 blob,然后将 blob 转换为 base64 并将图像插入到标签的 src 中。该解决方案需要清除两个管道:一个是用于进行 XHR 调用的自定义管道,另一个是 Angular 的内置管道async
。这是我们的定制管道:
import { Pipe, PipeTransform } from '@angular/core';
import { Http, RequestOptions, Headers, ResponseContentType } from @angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
@Pipe({name: 'image'})
export class ImagePipe implements PipeTransform {
constructor(private http: Http) {}
transform(url: string) {
const headers = new Headers({'Authorization': 'MY TOKEN', 'Content-Type': 'image/*'}); /* tell that XHR is going to receive an image as response, so it can be then converted to blob, and also provide your token in a way that your server expects */
return this.http.get(url, new RequestOptions({headers: headers, responseType: ResponseContentType.Blob})) // specify that response should be treated as blob data
.map(response => response.blob()) // take the blob
.switchMap(blob => {
// return new observable which emits a base64 string when blob is converted to base64
return Observable.create(observer => {
const reader = new FileReader();
reader.readAsDataURL(blob); // convert blob to base64
reader.onloadend = function() {
observer.next(reader.result); // emit the base64 string result
}
});
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是你的html:
<img [src]="('https://www.w3schools.com/css/trolltunga.jpg' | image) | async" />
Run Code Online (Sandbox Code Playgroud)
我们使用管道获取 base64 字符串的 observable,并将async
实际发出的字符串插入src
标签内。
如果您查看Network
选项卡内部,您将看到在 XHR 调用期间提供了您的 Authorization 标头:
您需要记住的一件事是 CORS:您的图像服务服务器应配置为接受来自运行 Angular 应用程序的域的图像的 XHR 调用,此外,您必须提供自定义的绝对 url管道,否则它将向 Angular 应用程序的域本身发出请求。
归档时间: |
|
查看次数: |
7739 次 |
最近记录: |