通过 jQuery 下载时 Zip 文件无效 [重复]

Posted

技术标签:

【中文标题】通过 jQuery 下载时 Zip 文件无效 [重复]【英文标题】:Zip file invalid when downloading via jQuery [duplicate] 【发布时间】:2021-12-08 12:21:12 【问题描述】:

我正在开发一个 MVC 站点,以允许客户选择多个文档进行下载。我编写了允许他们单独生成任何交易的 PDF 的代码。新要求是允许选择行,然后生成一个包含所有生成的 PDF 的 zip 文件。

该网页在顶部设置了一个过滤器部分,之后表格中的事务和表格下方是分页控件。整个页面被包裹在一个表单中。由于我需要的数据已经在表格中,我将页面分成两种形式,一种用于过滤,一种用于下载。问题是分页控件是表单的一部分,需要过滤控件与页面一起提交。我将分页移到表格上方,这样它就可以成为过滤器表单的一部分,同时保留表格以用于我的多个 PDF 下载操作。这很好用,但我们有几个页面使用这种设置,所以为了保持网站统一,我必须将分页移动到所有这些页面的顶部。此外,营销部门并不热衷于这种变化,但要了解是否需要这样做。

由于我无法在表单中嵌入表单,因此我决定为每一行的复选框添加属性,并使用 jQuery 遍历所有属性并提取我的操作所需的数据。这部分效果很好,我得到了我需要的所有数据,我把它们放到一个对象数组中,做 json 字符串化,我的控制器很高兴。我找到了这个问题:Download a file by jQuery.Ajax 并尝试了一些答案。经过一些参数摆弄后,我让它返回二进制数据。我找到了一个解决方案,允许我的 ajax 调用下载它收到的文件并且看起来它正在工作,但是当我打开 zip 文件时,我得到“Windows 无法打开文件夹。压缩(压缩)文件夹 'c:\path\deliveries. zip' 无效”。

我知道该操作之前有效,因为它在连接为表单时有效,我只是在 _blank 目标上打开了表单操作。我应该提到我坚持使用 jQuery 1.11,因为这个应用程序很大,更新 jQuery 需要一周或更长时间来测试所有页面和功能。

这是控制器代码(可以正常工作)

[HttpPost]
public ActionResult GetMultiplePdfs(List<DeliveryPdfDownloadViewModel> deliveries)

    using (var memoryStream = new MemoryStream())
    
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        
            foreach (var delivery in deliveries)
            
                string file = $"Delivery-delivery.CustomerNumber-delivery.siteNumber-delivery.Time.ToString("yyyyMMddhhmmss").pdf";
                var url = $"/api/Delivery?customerNumber=delivery.CustNum&shipToNumber=delivery.ShipToNum&startTime=delivery.StartTime";
                var response = _client.GetAsync(url).GetAwaiter().GetResult();

                var pdf = archive.CreateEntry(file);
                using(var entryStream = pdf.Open())
                using(var streamWriter = new StreamWriter(entryStream, Encoding.UTF8))
                
                    var byteArray = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
                    streamWriter.BaseStream.Write(byteArray, 0, byteArray.Length);
                    streamWriter.Flush();
                
            
        
        logger.Info($"Successfully created zip file with deliveries.Count() PDF documents in it");
        return File(memoryStream.ToArray(), "application/zip", "deliveries.zip");
    

这里是 jQuery

 $.ajax(
    url: "@Url.Action("GetMultiplePdfs")",
    type: "POST",
    //dataType: 'application/zip',
    data:  "deliveries": data ,
    //xhrFields: 
    //    responseType: "blob"
    //,
    success: function (result) 
        let bobloblaw = new Blob([result]);
        let a = document.createElement('a');
        a.href = window.URL.createObjectURL(bobloblaw);
        a.download = "deliveries.zip";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        window.URL.revokeObjectURL(a.href);
    ,
    error: function () 
        alert("Unable to download PDFs")
    
    );

    //subscribeRequest.done(function (data) 
    //    console.log(data);
    //);

我包含了一些我尝试过的注释掉的行。在我摆脱 contentType 之前,我的操作无法识别我发送的 json。我的 ajax 调用失败,直到我删除了 dataType;我尝试使用 subscribeRequest 而不是成功,但结果相同。我尝试将 ajax 调用中的 responseType 设置为 blob。创建 Blob 时,我尝试了 type: "application/zip" ,还尝试了从上面的链接中找到的 "application/octetstream"。

【问题讨论】:

【参考方案1】:

我让它工作了。我找到了另一个问题:Recieving a Zip file as response on AJAX request

我尝试了以下代码,它成功了!!!

fetch("@Url.Action("GetMultiplePdfs")", 
    method: "POST",
    headers: 
        "content-type": "application/json"
    ,
    body: JSON.stringify(data)
)
    .then((response) => 
        response.blob().then((blob) => 
            const downloadUrl = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.setAttribute('href', downloadUrl);
            link.setAttribute('download', 'file');
            link.style.display = 'none';
            document.body.appendChild(link);
            link.click();
            window.URL.revokeObjectURL(link.href);
            document.body.removeChild(link);
        )
    );

我不确定 fetch 和 ajax 之间有什么区别,但不知何故这正在返回我的文件。 zip 文件打开,PDF 文件完好无损。

【讨论】:

以上是关于通过 jQuery 下载时 Zip 文件无效 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Zip 下载后重定向或刷新页面

用老毛桃U盘重装系统时提示无效镜像文件怎么办

通过电子邮件发送的 Zip 在第一次尝试时无效

ZipArchive创建无效的ZIP条目

来自 Flask send_file 的 Zip 文件无效

使用 CURL 下载的档案无效