使用 MVC 4.0,我使用以下代码从 ajax 源(使用最新的 firefox)从服务器创建下载文件:
如果输出涉及的是文本文件(例如 csv 或 txt 文件),这可以正常工作,但是,当涉及到 zip 或 xlsx 等文件时,下载的文件似乎与原始源不同(即在服务器中生成的 zip 为 15K ,但下载的是26K)
我已经挣扎了几天,请问是否有人应该解释一下为什么它适用于 csv/text 文件,但不适用于 zip 或 xlsx 文件?
非常感谢
控制器:
Public Function download(dataIn As myObject) As ActionResult
'some processing
'generated zip files and return with the full path
Dim zipFullPath = generateFiles(dataIn)
Response.Clear()
Response.ContentType = "application/zip"
Response.AddHeader("Content-Disposition", "attachment; filename=Out.zip")
Dim fileLength = New IO.FileInfo(zipFullPath).Length
'fileLength reads about 15K of data
Response.AddHeader("Content-Length", fileLength)
Response.TransmitFile(zipFullPath)
Response.End()
Return View()
End Function
JavaScript:
$.ajax({
type: "POST",
url: "reports/download",
data: jData,
contentType: "application/json; charset=utf-8",
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
//Here is the problem, the original is about 15k,
// but the download file is about 26K
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
},
error: function (data) {
alert('Error');
}
});