Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html Angular 4图像与承载头异步_Html_Angular_Bearer Token - Fatal编程技术网

Html Angular 4图像与承载头异步

Html Angular 4图像与承载头异步,html,angular,bearer-token,Html,Angular,Bearer Token,我的任务是使用auth头发出异步映像请求。我有如下图像路径: <img src="{{file.src}}"/> 我需要为这样的请求向报头添加承载令牌。页面包含许多图像,因此ajax请求不适合。 不知道如何执行此操作。现在,无法仅通过html中的标记进行授权调用,浏览器不为此提供API,因此您必须发出XHR请求。这里有一个解决方法:通过XHR获取图像,将其转换为blob,然后将blob转换为base64,并将图像插入标记的src。此解决方案需要两个管道才能清除:一个是用于进行X

我的任务是使用auth头发出异步映像请求。我有如下图像路径:

<img src="{{file.src}}"/>

我需要为这样的请求向报头添加承载令牌。页面包含许多图像,因此ajax请求不适合。
不知道如何执行此操作。

现在,无法仅通过html中的标记进行授权调用,浏览器不为此提供API,因此您必须发出XHR请求。这里有一个解决方法:通过XHR获取图像,将其转换为blob,然后将blob转换为base64,并将图像插入标记的src。此解决方案需要两个管道才能清除:一个是用于进行XHR调用的自定义管道,另一个是Angular的内置管道
async
。这是我们的定制管道:

从'@angular/core'导入{Pipe,PipeTransform};
从@angular/Http'导入{Http,RequestOptions,Headers,ResponseContentType};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/map';
导入'rxjs/add/operator/switchMap';
@管道({name:'image'})
导出类ImagePipe实现PipeTransform{
构造函数(私有http:http){}
转换(url:string){
const headers=new headers({'Authorization':'MY TOKEN','Content Type':'image/*'});/*告诉XHR将接收一个映像作为响应,这样它就可以被转换为blob,并以服务器期望的方式提供您的令牌*/
返回此.http.get(url,new RequestOptions({headers:headers,responseType:ResponseContentType.Blob}))//指定响应应被视为Blob数据
.map(response=>response.blob())//获取blob
.switchMap(blob=>{
//返回新的observable,当blob转换为base64时,它将发出base64字符串
返回可观察的。创建(观察者=>{
const reader=new FileReader();
reader.readAsDataURL(blob);//将blob转换为base64
reader.onloadend=函数(){
observer.next(reader.result);//发出base64字符串结果
}
});
});
}
}
下面是您的html:

<img [src]="('https://www.w3schools.com/css/trolltunga.jpg' | image) | async" />

我们使用管道获取base64字符串的可观测值,并使用
async
将实际发出的字符串插入
src
标记中

如果查看
网络
选项卡,您将看到在XHR调用期间提供了授权标头:
您需要记住的一件事是CORS:您的图像服务服务器的配置方式应使其能够接受来自运行Angular应用程序的域的图像的XHR调用,此外,您还必须提供自定义管道的绝对URL,否则,它将向Angular应用程序的域本身发出请求。

如果您已经实现了HttpInterceptor for api,您可以通过让interceptor处理头来简化上述管道代码。下面是使用HttpClient更新的版本

@Pipe({
  name: 'image',
})
export class ImagePipe implements PipeTransform {
  constructor(
    private http: HttpClient,
    private config: ConfigProvider
  ) { }

  transform(url: string) {
    return this.http.get(url, {responseType: "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
          }
        });
      });
  }
}
`
下面是一个例子:

@Injectable()
导出类TokenInterceptor实现HttpInterceptor{
构造函数(私有配置:ConfigProvider){}
截取(req:HttpRequest,next:HttpHandler):可观察{
const authReq=req.clone({
集合标题:{
授权:this.config.getAuthorization(),
“X-App-ClientId”:此.config.authentication['X-App-ClientId']
}
});
返回next.handle(authReq);
}
}

假设您已经实现了一个HttpIntercepter来添加标头,下面是一个实际可行的解决方案(在第4章中):

从'@angular/core'导入{Pipe,PipeTransform};
从'@angular/common/http'导入{HttpClient};
从“rxjs/Observable”导入{Observable};
@烟斗({
名称:“安全”
})
导出类SecurePipe实现PipeTransform{
构造函数(私有http:HttpClient){}
转换(url:string){
返回新的可观察对象((观察者)=>{
//这是一个微小的空白图像
下一步('data:image/gif;base64,r0lgodlhaqaabaaaach5baekaaaaaaaaaaaaaaaaitaeaow==');
//来自观察者的next和error回调
const{next,error}=观察者;
this.http.get(url,{responseType:'blob'}).subscribe(response=>{
const reader=new FileReader();
reader.readAsDataURL(响应);
reader.onloadend=函数(){
observer.next(reader.result);
};
});
返回{unsubscribe(){}};
});
}
}
您可以这样使用它:

<img src="{{file.src}}"/>

以前的解决方案有很大的缺陷。我不保证这是完美的,但它实际上是测试和工作为我

您无法返回从http.get获得的可观测值!我不知道为什么以前的解决方案假设你可以。http.get的observable表示何时从服务器检索数据。但是,在此之后还必须完成另一个异步过程:对reader.readAsDataURL的调用。因此,您需要创建一个可观察对象,在该过程完成后,您将调用它

此外,如果您没有立即将某些内容放入图像中,浏览器仍将尝试使用HTTP加载图像,并且您的JavaScript控制台中会出现错误。这就是第一个observer.next调用的原因,该调用将插入一个空的、微小的GIF图像


这种方法的一个问题是,如果图像被多次使用,每次都会加载。即使浏览器缓存,每次也要转换到base64。我创建了一个缓存来存储图像,这样在第一次之后就不需要再进行查询了。

Angular 5的解决方案以及Armen Vardanyan和Charles的混合解决方案。Armen的解决方案适用于Angular 5,但首先尝试加载url。为了解决这个问题,我加入了查尔斯的小空白图像:

@Pipe({name: 'secure'})
export class SecurePipe implements PipeTransform {
  constructor(private http: Http,
    public g: BaseGroupService) {}

    transform(url: string) {

      return new Observable<string>((observer) => {
        observer.next('data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==');
        const {next, error} = observer;

        const headers = new Headers({'Authorization': 'TOKEN', 'Content-Type': 'image/*'}); 
        this.http.get(url, new RequestOptions({headers: headers, responseType: ResponseContentType.Blob})).subscribe(response => {
          const reader = new FileReader();
          reader.readAsDataURL(response.blob());
          reader.onloadend = function() {
            observer.next(reader.result);
          };
        });
        return {unsubscribe() {  }};
      });
    }
}
@Pipe({name:'secure'})
导出类SecurePipe实现PipeTransform{
构造函数(私有http:http,
公共g:BaseGroupService){}
转换(url:string){
返回新的可观察对象((观察者)=>{