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?
Right-click the image, then click one of the following depending on your browser: Chrome - Click Copy image address. Firefox - Click Copy Image Location. Microsoft Edge - Click Copy link.
Any image is merely a sequence of bytes structured in accordance with whatever underlying format used to represent it, eg color data, layers, dimensions, etc. The significance of any byte(s) you see during debugging is entirely dependent upon the native format of the image, eg PNG, TIFF, JPEG, BMP, etc.
Images are binary data - this is easily represented as byte arrays. The image in the sample is stored in the database as a BLOB - not a string or location, that is, it is binary data.
whole bytes (24 bits) are used to represent the colour of each pixel. This is split up into one byte for each of the primary colours of light, red, green and blue. This is because computer displays uses these primary colours of light to display all the different colours we see on the screen.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With