Подтвердить что ты не робот

Получить изображения или байтовые данные с помощью 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();
            } );
    }

Но я не получаю от него никакого изображения, и запись данных ответа показывает большую строку, которая является данными изображения.

У вас есть взломать это?

4b9b3361

Ответ 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();