Get Image or byte data with http

僤鯓⒐⒋嵵緔 提交于 2019-11-27 19:28:55
tschuege

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));
        })

Using the new Angular HttpClient is really easy to achieve this. Going off of tschuege's approach, it would be:

return this._http.get('/api/images/' + _id, {responseType: 'blob'}).map(blob => {
  var urlCreator = window.URL;
  return this._sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
})

The key is to set the responseType as 'blob' so that it doesn't attempt to parse it as JSON

I think that you missed to set the responseType on your request. Right now it's a bit tricky because it's not supported.

The workaround would be to override the BrowserXhr class to set the responseType on the xhr object itself...

You could extend the BrowserXhr:

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor() {}
  build(): any {
    let xhr = super.build();
    xhr.responseType = 'arraybuffer';
    return <any>(xhr);
  }
}

and override the BrowserXhr provider with the extended class:

bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);

The problem is here that you don't override for all requests. At the bootstrap level, it will override everything. So you could provide it in a sub injector within the providers attribute of the impacted component...

Here is a working plunkr: https://plnkr.co/edit/tC8xD16zwZ1UoEojebkm?p=preview.

This JSFiddle could help you: https://jsfiddle.net/virginieLGB/yy7Zs/936/

The method is, as you wanted, creating a Blob from the URL provided

// Image returned should be an ArrayBuffer.
var xhr = new XMLHttpRequest();

xhr.open( "GET", "https://placekitten.com/500/200", true );

// Ask for the result as an ArrayBuffer.
xhr.responseType = "arraybuffer";

xhr.onload = function( e ) {
    // Obtain a blob: URL for the image data.
    var arrayBufferView = new Uint8Array( this.response );
    var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
    var urlCreator = window.URL || window.webkitURL;
    var imageUrl = urlCreator.createObjectURL( blob );
    var img = document.querySelector( "#photo" );
    img.src = imageUrl;
};

xhr.send();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!