【发布时间】:2017-11-25 03:50:17
【问题描述】:
我有一个名为 DownloadZipFile 的服务,它可以整理数据,然后构建一个 Zip 文件以供下载。此服务将包含流的响应返回到文件
服务:
[HttpPost]
public ActionResult DownloadZipFile(string zipData)
{
try
{
// Create the Zip File.
using (MemoryStream zipStream = DownloadHelper.BuildZipFileData(zipData))
{
// Build up the reponse including the file.
HttpContext.Response.ClearContent();
HttpContext.Response.ClearHeaders();
HttpContext.Response.Clear();
HttpContext.Response.Buffer = true;
HttpContext.Response.ContentType = "application/zip";
HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=MyZipFile.zip;");
HttpContext.Response.BinaryWrite(zipStream.ToArray());
HttpContext.Response.End();
}
}
catch (Exception e)
{
// Log the error.
_logService.Error(LogHelper.GetWebRequestInfo(ControllerContext.HttpContext.Request), e);
}
}
如果我这样调用服务,它将正确下载并打开 zip 文件。
服务调用 #1
var form = $("<form></form>").attr('action', "DownloadZipFile").attr("method", "post");
form.append($("<input></input>").attr("type", "hidden").attr("name", "zipData").attr('value', escape(JSON.stringify(zipData))));
form.appendTo('body').submit().remove();
但是,如果我在将响应从响应转换为 blob 时使用 AJAX Post 调用,则大小比我发送的要大得多。
服务电话#2:
$.post("DownloadZipFile", { zipData: escape(JSON.stringify(zipData)) },
function (data, status, response) {
var filename = "";
var disposition = response.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 = response.getResponseHeader('Content-Type');
var blob = new Blob([data], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
var a = document.createElement("a");
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
}
});
使用服务调用 #2 我得到的 Zip 文件已损坏
可能是编码吗?我检查了正确和错误 Zip 文件之间的数据,它们看起来像这样:
正确的邮编:
PK ú‚ÐJmÇ´¸g € BOM.csvu‘ËNÃ0E÷HüÃÈ+ÆÑØy/›”WÔðH[Ä64IÕ¦|>‰_ÀN(-¢l®,Ýã;wìÏ÷‡m^Ö³ú 35VkUŽtÕf6)óºZcZjqz"0dÒ³ü9TÓ%yd#^3Ö∼R›¡kÙMYæt2'Òâ¦É½dÈhO¶"BXÁ?ùÚ"Ç
损坏的邮编:
PK ï¿¿ï¿¿ï¿¿g ï¿¿ BOM.csvuï¿¿ï¿¿ï¿¿Eï¿¿ï¿¿+ï¿¿ï¿¿/ï¿¿ï¿¿Wï¿ ¿H[ï¿¿4IÕ¦|>ï¿¿_ï¿¿(-ï¿¿lï¿¿,ï¿¿;wï¿¿ï¿¿ï¿¿m^ֳ￿kUï¿¿tï¿ ¿6)ï¿¿Zjqz"0dҳ￿yd#ï¿¿3Ö~Rï¿¿ï¿¿kï¿¿MYï¿¿2'￿￿ɽdï¿¿Oï¿¿"BXï¿¿ï¿ ¿ï¿¿,ï¿¿ ï¿¿ï¿¿ï¿¿ï¿¿ï¿¿ï¿¿ï¿¿Aï¿¿VG]3
似乎文件的编码方式不同。大家觉得呢?
【问题讨论】:
-
差异可能与
DownloadHelper.BuildZipFileData和new Blob([escape(JSON.stringify(zipData))], { type: type })的工作方式有关。似乎不同的字节处理模式对输出保存在 ZIP 文件中的二进制数据产生了进一步的影响。 -
是的,但如果只是通过创建虚拟表单(服务调用#1)调用服务,我只是正确下载了 Zip 文件,但我没有得到任何其他状态。我想要的是得到对呼叫的响应,以便我可以告诉我的应用程序我已正确下载。不幸的是,对 Blob 的响应似乎改变了编码。我必须在哪里强制?
-
您不能真正使用 jQuery Ajax 下载二进制数据。见here
-
这很有帮助,我使用了原生 XMLHttpRequest 并且它有效。谢谢! :)
标签: javascript c# ajax post blob