通过 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 文件无效 [重复]的主要内容,如果未能解决你的问题,请参考以下文章