Angular base64图像管道,超出最大调用堆栈大小 [英] Angular base64 image pipe, Maximum call stack size exceeded

查看:157
本文介绍了Angular base64图像管道,超出最大调用堆栈大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须将图片网址转换为base64编码的字符串(因为这个

I have to convert Image urls to base64 encoded strings (because of this)

import { Pipe, PipeTransform } from '@angular/core';


declare var base64;

@Pipe({
  name: 'tobase64'
})
export class Tobase64Pipe implements PipeTransform {

  transform(value: any, args?: any): any {
    var xmlHTTP = new XMLHttpRequest();
    xmlHTTP.open('GET', value, true);
    xmlHTTP.responseType = 'arraybuffer';
    xmlHTTP.onload = (e) => {
        console.log('e',e);
      var arr = new Uint8Array(e.currentTarget.response);
      var raw = String.fromCharCode.apply(null, arr);
      var b64 = base64.encode(raw);
       var dataURL = "data:image/png;base64," + b64;
      return dataURL;
    };
    xmlHTTP.send();

    return null;
  }

}

Html

<image x="0" y="0" width="500" height="500" [attr.xlink:href]="'assets/hand.jpg' | tobase64"    mask="url(#hole)" />  

错误:

ERROR RangeError: Maximum call stack size exceeded


推荐答案

从管道发出HTTP请求是完全可以的。在你的情况下,你最终只会做一个。考虑一下:如果将 img src 属性绑定到可以动态更改的属性,您最终会生成任何时候属性更改服务器调用;无论该呼叫是XHR呼叫还是对图像的简单请求,这都不是什么大问题。我对管道不太了解的唯一两件事是:

It is completely okay to do HTTP requests from a pipe. In your case you will eventually do just one. Consider this: if you bind a src attribute of an img to a property that can change dynamically, you will eventually make a server call any time the property changes; it's not really a big deal whether that call is an XHR call or a simple request for an image. The only two things I do not quite understand about your pipe is following:


  1. 为什么使用XMLHTTPRequest而不是Angular的Http或HttpClient服务?

  2. 为什么管道返回 null ?似乎即使你没有得到任何错误,你仍然不会得到结果

  1. Why use XMLHTTPRequest rather than Angular's Http or HttpClient services?
  2. Why does your pipe return null? It seems that even if you did not get any errors, you won't still get the result

这个解决方案将需要两个管道要清楚:一个是用于进行XHR调用的自定义管道,另一个是Angular的内置管道 async 。这是我们的自定义管道:

This solution will require two pipes to be clear: one is a custom pipe for making XHR calls and the other is the Angular's built-in pipe async. Here is our custom pipe:

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: 'toBase64'})
export class ImagePipe implements PipeTransform {
  constructor(private http: Http) {}

  transform(url: string) {
  const headers = new Headers({'Content-Type': 'image/*'}); /* tell that XHR is going to receive an image as response, so it can be then converted to blob */
  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
        }
     });
   });
  }
}

这里有你的html:

<image x="0" y="0" width="500" height="500" [attr.xlink:href]="('assets/hand.jpg' | toBase64) | async"    mask="url(#hole)" /> 

我们使用我们的管道来获取base64字符串的可观察性,并且 async 将实际发出的字符串插入 src 标记内。

We use our pipe to get an observable of a base64 string, and async to insert the actual emitted string inside the src tag.

您需要记住的一件事是CORS:您的图像服务器应配置为接受XHR调用来自您的Angular应用程序的域的图像在运行时,您还必须向自定义管道提供绝对URL,否则它将向Angular应用程序的域本身发出请求。但在你的情况下,我假设你从你自己的应用程序提供图像,所以这不应该是一个问题。

One thing you need to keep in mind is CORS: your image serving server should be configured in a way that it accepts XHR calls for images from the domain your Angular app is running on, also, you will have to provide absolute urls to the custom pipe, otherwise it will make requests to the Angular app's domain itself. But in your case I assume you serve images from your own app, so this should not really be a concern.

这篇关于Angular base64图像管道,超出最大调用堆栈大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆