Загрузка файла Angular 2: поврежденный результат

Я пытаюсь загрузить файл, используя Angular 2/TypeScript и Web API. Проблема, с которой я сталкиваюсь, заключается в том, что при загрузке текстового файла файл является файлом, но при попытке загрузить файл PDF, например, он поврежден. Содержимое скачанного файла чушь вздор.

TypeScript, который я использую, выглядит следующим образом:

downloadFile(fileId: string): Observable<File> {
    this.applicationsUrl = `${APIConfig.BaseUrl}/documents/download/${fileId}/`;

    let headers = new Headers({ 'Content-Type': 'application/json', 'MyApp-Application' : 'AppName' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.applicationsUrl, '', options)
        .map(this.extractContent)
        .catch(this.handleError);
}

private extractContent(res: any) {
    let blob: Blob = new Blob([res._body], { type: 'application/pdf'});
    window['saveAs'](blob, 'test.pdf');
}

Окно ['saveAs'] - это просто обходной путь для доступа к функциям JavaScript FileSaver.js.

Кроме того, я установил res:Response для res:any, чтобы я мог получить доступ к свойству private _body в JavaScript без сбоя компиляции в TypeScript.

Любая помощь будет принята с благодарностью.

2 ответа

Решение

Начиная с Angular RC5 у вас должен работать следующий код:

downloadFile(fileId: string): Observable<File> {
this.applicationsUrl = `${APIConfig.BaseUrl}/documents/download/${fileId}/`;

let headers = new Headers({ 'Content-Type': 'application/json', 'MyApp-Application' : 'AppName', 'Accept': 'application/pdf' });
let options = new RequestOptions({ headers: headers, responseType: ResponseContentType.Blob });

return this.http.post(this.applicationsUrl, '', options)
    .map(this.extractContent)
    .catch(this.handleError);
}

private extractContent(res: Response) {
    let blob: Blob = res.blob();
    window['saveAs'](blob, 'test.pdf');
}

У меня была похожая проблема, и я установил Accept-Header в application/pdf, responseType to Blob и доступ к BLOB-объекту с помощью соответствующего метода в Response решил эту проблему для меня:) (я тоже использую FileSaver)

У нас была похожая проблема, и нам пришлось настроить конвертер сообщений на стороне пружины. Приведенный ниже фрагмент кода взят из конфигурационного файла Spring:

    @Override
     public void configureMessageConverters(List<HttpMessageConverter<?>> 
         converters) {
    //Here we add our custom-configured HttpMessageConverter
   /* Message converter for supporting Hibernate lazy objects */
    converters.add(jacksonMessageConverter());
    converters.add(byteArrayHttpMessageConverter());
    super.configureMessageConverters(converters);
}

    public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
    ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
    arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
    return arrayHttpMessageConverter;
} 

private List<MediaType> getSupportedMediaTypes() {
    List<MediaType> list = new ArrayList<MediaType>();
    list.add(MediaType.APPLICATION_OCTET_STREAM);
    list.add(MediaType.parseMediaType("application/pdf"));
    return list;
}

Более подробную информацию о настройке конвертеров сообщений можно найти здесь: - http://www.baeldung.com/spring-httpmessageconverter-rest

Вам все еще нужно добавить заголовок "Принять" в запросе, как ответил Крис. Это поможет сопоставить ответ с соответствующим конвертером сообщений, настроенным на стороне пружины.

Другие вопросы по тегам