Загрузка файла 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
Вам все еще нужно добавить заголовок "Принять" в запросе, как ответил Крис. Это поможет сопоставить ответ с соответствующим конвертером сообщений, настроенным на стороне пружины.