Angular (5) httpclient наблюдать и отвечатьType: 'blob'

Контекст: я пытаюсь загрузить двоичный файл из бэкэнда (для которого требуются некоторые данные, отправленные в виде json-body) и сохранить его с помощью средства сохранения файлов, используя имя файла, указанное бэкендом в заголовке расположения содержимого. Я думаю, что для доступа к заголовкам мне нужен HttpResponse.

Но я не могу использовать angular метод HttpClient.post<T>(...): Observable<HttpResponse<T>>; с BLOB-объектами.

Когда я звоню

this.httpclient.post<Blob>('MyBackendUrl', 
        params, 
        {observe: 'response', responseType: 'blob'});
the compiler complains about the 'blob' ('json' is accepted by the compiler):


error TS2345: Argument of type '{ observe: "response"; responseType: "blob"; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
  Types of property 'observe' are incompatible.
    Type '"response"' is not assignable to type '"body"'.

Когда я помещаю параметры в собственный объект, как показано в qaru.site/info/14354058/... (но без "as"...), вызывается сообщение post (...): Observable, и я не могу получить доступ к заголовкам.

Кстати, даже простой пример return this.http.get<Blob>('backendUrl', {responseType: 'blob'});, как видно, например, у меня qaru.site/info/14534937/... не работает.

Используемые версии

  • Угловая версия: 5.0.3 (будет обновлена до 5 последних версий через неделю)
  • машинопись: 2.4.2
  • веб-пакет: 3.8.1

Ответ 1

При использовании функции observe:response не набирайте вызов (post<Blob>(...)), так как возвращаемый Observable будет HttpResponse. Поэтому это должно работать:

this.httpclient.post('MyBackendUrl', 
    params,
    {observe: 'response', responseType: 'blob'}
);

Почему это происходит, есть две версии метода post, один с общим типом, один без:

/**
     * Construct a POST request which interprets the body as JSON and returns the full event stream.
     *
     * @return an 'Observable' of all 'HttpEvent for the request, with a body type of 'T'.
     */
    post<T>(url: string, body: any | null, options: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'events';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<HttpEvent<T>>;
    /**
     * Construct a POST request which interprets the body as an 'ArrayBuffer' and returns the full response.
     *
     * @return an 'Observable' of the 'HttpResponse' for the request, with a body type of 'ArrayBuffer'.
     */
    post(url: string, body: any | null, options: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'response';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
    }): Observable<HttpResponse<ArrayBuffer>>;

Ответ 2

Вы можете использовать как

responseType: 'blob' as 'json'