Search code examples
javascriptangularangular2-http

Get Image or byte data with http


For a web application I need to get my images with an ajax request because we have signature + authentication on our API, so we can't get images using a simple <img src="myapi/example/145"/>

Since we're using angular2, we obviously looked for blob or something like that, but as stated in static_response.d.ts file:

/**
 * Not yet implemented
 */
blob(): any;

So okay, I can't do it for now, I have to wait for thie feature to be implemented.

But problem is I can't wait so I need a hotfix or a little hack to be able to get image data from response and I'll be able to remove my hack and set the blob() method call to be good when it will be implemented.

I tried this:

export class AppComponent {
    constructor(private api:ApiService, private logger:Logger){}
    title = 'Tests api';
    src='http://placekitten.com/500/200'; //this is src attribute of my test image
    onClick(){ //Called when I click on "test" button
        this.api.test().then(res => {
            console.log(res._body);
            var blob = new Blob([new Uint8Array(res._body)],{
                type: res.headers.get("Content-Type")
            });
            var urlCreator = window.URL;
            this.src = urlCreator.createObjectURL(blob);
        });
    }
}

with ApiService.test() method:

test():Promise<any> {
        return this.http.get(this._baseUrl + "myapi/example/145", this.getOptions())
//getOptions() is just creating three custom headers for     
//authentication and CSRF protection using signature
            .toPromise()
            .then(res => {
                    this.logger.debug(res);
                if(res.headers.get("Content-Type").startsWith("image/")){
                    return res;
                }
                return res.json();
            })
            .catch(res => {
                this.logger.error(res);
                return res.json();
            } );
    }

But I don't get any image from it and logging the response data shows a big string which is image data.

Do you have a hack to achieve this?


Solution

  • It is not necessary to extend BrowserXhr anymore. (Tested with angular 2.2.1) RequestOptionsArgs now has a property responseType: ResponseContentType which can be set to ResponseContentType.Blob

    Using DomSanitizer

    import {DomSanitizer} from '@angular/platform-browser';
    

    This example also creates a sanitized url that can be bound to the src property of an <img>

    this.http.get(url,  {
                            headers: {'Content-Type': 'image/jpg'},
                            responseType: ResponseContentType.Blob
                        })
            .map(res => {
                return new Blob([res._body], {
                    type: res.headers.get("Content-Type")
                });
            })
            .map(blob => {
                var urlCreator = window.URL;
                return  this.sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
            })