【问题标题】:Angular 2 downloading a file: corrupt resultAngular 2下载文件:损坏的结果
【发布时间】:2016-12-12 03:24:49
【问题描述】:

我正在尝试使用 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');
}

window['saveAs'] 只是访问 JavaScript FileSaver.js 函数的一种解决方法。

此外,我已将 res:Response 设置为 res:any,因此我可以在 JavaScript 下访问私有 _body 属性,而不会在 TypeScript 中编译失败。

任何帮助将不胜感激。

【问题讨论】:

    标签: typescript angular


    【解决方案1】:

    从 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 设置为 Blob 并通过响应上的相应方法访问 blob 为我解决了这个问题:) (我也在用 FileSaver)

    【讨论】:

    • 您如何使用 FileSaver?你能举一个在 Typescript 中使用它的例子吗?
    【解决方案2】:

    我们遇到了类似的问题,不得不在 spring 端配置一个 messageConverter。下面的代码 sn-p 来自 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

    您仍然需要在请求中添加“接受”标头,正如 Chris 所回答的那样。这将有助于将响应映射到在 spring 端配置的适当消息转换器。

    【讨论】:

    • 这可能为时已晚,但可能会使其他人受益!
    猜你喜欢
    • 2020-03-15
    • 2014-10-26
    • 2015-07-14
    • 2015-07-16
    • 2017-12-04
    • 2019-01-28
    • 1970-01-01
    • 2019-08-19
    • 2023-03-05
    相关资源
    最近更新 更多