下载文件并将其保存在浏览器的本地存储中

Posted

技术标签:

【中文标题】下载文件并将其保存在浏览器的本地存储中【英文标题】:Download and save file in browser's local storage 【发布时间】:2016-02-19 00:13:10 【问题描述】:

我有一个提供文件的 Java Web 应用程序:

@RequestMapping(value = "/pdf/download", method = RequestMethod.GET)
public void download(
        HttpServletRequest request, 
        HttpServletResponse response, 
        @RequestParam(value = "id", required = true) Long id) throws IOException 

    File pdfFile = pdfFileManager.getFromId(id);

    response.setContentType("application/pdf");
    response.addHeader("Content-Disposition", "attachment; filename=download");
    response.setContentLength((int) pdfFile.length());

    FileInputStream fileInputStream = null;
    OutputStream responseOutputStream = null;

    try    
        fileInputStream = new FileInputStream(pdfFile);
        responseOutputStream = response.getOutputStream();

        int bytes;
        while ((bytes = fileInputStream.read()) != -1) 
            responseOutputStream.write(bytes);
        

        responseOutputStream.flush();
     finally 
        fileInputStream.close();
        responseOutputStream.close();
    

我在客户端检索文件并使用 FileReader 对其进行 base64 编码:

$.ajax(
    url: "/pdf/download?id=" + id,
    dataType: "application/pdf",
    processData: false
).always(function(response) 
    if(response.status && response.status === 200) 
       savePdf(response.responseText, "download_" + id);
     
); 

function savePdf(pdf, key) 
    var blob = new Blob([pdf], type: "application/pdf");
    var fileReader = new FileReader();

    fileReader.onload = function (evt) 
        var result = evt.target.result;

        try 
            localStorage.setItem(key, result);
         catch (e) 
            console.log("Storage failed: " + e);
        
    ;

    fileReader.readAsDataURL(blob);

问题是本地存储中保存的值不正确。编码数据与我使用this snip 上传 PDF 时得到的数据不同。我不知道问题是我如何在客户端提供文件或编码过程。

存储的值是这样的

data:application/pdf;base64,JVBERi0xLjQKJe+/ve+/ve+/ve+/vQoxIDAgb...

而不是

data:application/pdf;base64,JVBERi0xLjQKJeHp69MKMSAwIG9iago8PC9Ue...

【问题讨论】:

【参考方案1】:

解决了将请求的响应类型设置为blob的问题:

var xhr = new XMLHttpRequest(); 
xhr.open("GET", "/pdf/download?id=" + id); 
xhr.responseType = "blob";
xhr.onload = function() 
    if(xhr.status && xhr.status === 200) 
        savePdf(xhr.response, "download_" + id);
     

xhr.send();

function savePdf(pdf, key) 
    var fileReader = new FileReader();

    fileReader.onload = function (evt) 
        var result = evt.target.result;

        try 
            localStorage.setItem(key, result);
         catch (e) 
            console.log("Storage failed: " + e);
        
    ;

    fileReader.readAsDataURL(pdf);

【讨论】:

以上是关于下载文件并将其保存在浏览器的本地存储中的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SQL Server 表中读取图像数据(存储 word 文档)并将其保存到本地文件夹

从url下载pdf,在flutter中保存到android中的手机本地存储

将文件加载到应用程序本地存储

Xamarin.Forms 将文件 (pdf) 保存在本地存储中并使用默认查看器打开

使用 Python 将 Blob 下载到本地存储

Java / Android - 读取、操作 XML 文件并将其保存到内部存储