Получить изображения или байтовые данные с помощью http
Для веб-приложения мне нужно получить мои изображения с помощью запроса ajax, потому что у нас есть подпись + аутентификация в нашем API, поэтому мы не можем получать изображения с помощью простого <img src="myapi/example/145"/>
Поскольку мы используем angular2, мы, очевидно, искали blob или что-то в этом роде, но, как указано в файле static_response.d.ts
:
/**
* Not yet implemented
*/
blob(): any;
Так хорошо, я не могу сделать это сейчас, я должен ждать, когда эта функция будет реализована.
Но проблема в том, что я не могу ждать, поэтому мне нужно исправление или небольшой взлом, чтобы иметь возможность получать данные изображения из ответа, и я смогу удалить свой хак и установить метод метода blob()
, чтобы быть хорошим когда он будет реализован.
Я пробовал это:
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);
});
}
}
с помощью метода ApiService.test()
:
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();
} );
}
Но я не получаю от него никакого изображения, и запись данных ответа показывает большую строку, которая является данными изображения.
У вас есть взломать это?
Ответы
Ответ 1
Больше не нужно расширять BrowserXhr
. (Протестировано с помощью angular 2.2.1)
RequestOptionsArgs теперь имеет свойство responseType: ResponseContentType
, которое можно установить на ResponseContentType.Blob
Использование DomSanitizer
import {DomSanitizer} from '@angular/platform-browser';
В этом примере также создается дезинфицированный URL-адрес, который может быть привязан к свойству src
<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));
})
Ответ 2
Я думаю, что вы пропустили установку responseType
по вашему запросу. Сейчас это немного сложно, потому что оно не поддерживается.
Обходным путем было бы переопределить класс BrowserXhr
, чтобы установить responseType
в самом объекте xhr
...
Вы можете расширить BrowserXhr
:
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.responseType = 'arraybuffer';
return <any>(xhr);
}
}
и переопределить поставщика BrowserXhr
с расширенным классом:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
Проблема заключается в том, что вы не переопределяете для всех запросов. На уровне начальной загрузки он будет отменять все. Таким образом, вы можете предоставить его в дополнительном инжекторе в атрибуте providers
ударного компонента...
Вот рабочий plunkr: https://plnkr.co/edit/tC8xD16zwZ1UoEojebkm?p=preview.
Ответ 3
Использование нового Angular HttpClient действительно легко достичь этого. Исходя из подхода tschuege, это будет:
return this._http.get('/api/images/' + _id, {responseType: 'blob'}).map(blob => {
var urlCreator = window.URL;
return this._sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
})
Ключ должен установить responseType как "blob", чтобы он не пытался анализировать его как JSON
Ответ 4
Этот JSFiddle может вам помочь:
https://jsfiddle.net/virginieLGB/yy7Zs/936/
Этот метод, как вы хотели, создавал Blob из предоставленного URL
// 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();