从 Web API 返回时 Zip 损坏?
Corrupted Zip while returning from Web API?
在我的 MVC 项目中,我有一个 AJAX 对 Web API 的调用。
我发送了一系列文档的路由,API(应该)压缩它们,returns 压缩文件。
self.zipDocs = function (docs, callback) {
$.ajax({
url: "../SharedAPI/documents/zip",
type: "POST",
data: docs,
contentType: "application/json",
success: function (data) {
var zip = new JSZip(data);
var content = zip.generate({ type: "blob" });
saveAs(content, "example.zip");
},
error: function (data) {
callback(data);
}
});
}
以及我在 Web 上的 ZipDocs 功能API(使用 DotNetZip 库):
[HttpPost]
[Route("documents/zip")]
public HttpResponseMessage ZipDocs([FromBody] string[] docs)
{
using (var zipFile = new ZipFile())
{
zipFile.AddFiles(docs, false, "");
return ZipContentResult(zipFile);
}
}
protected HttpResponseMessage ZipContentResult(ZipFile zipFile)
{
// inspired from
var pushStreamContent = new PushStreamContent((stream, content, context) =>
{
zipFile.Save(stream);
stream.Close(); // After save we close the stream to signal that we are done writing.
}, "application/zip");
return new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent };
}
但是当返回 Zip 时,我收到以下错误:
Uncaught Error: Corrupted zip: missing 16053 bytes.
真正奇怪的是,当我将压缩文件 API 保存到磁盘时 它被正确保存 我可以毫无问题地打开文件!
我做错了什么?我错过了什么吗?
请帮忙!
提前致谢。
两件事:
1/ $.ajax
处理文本响应并将尝试 (utf-8) 解码内容:您的 zip 文件不是文本,您将得到损坏的内容。 jQuery doesn't support binary content 所以你需要使用之前的 link 并在 jQuery 上添加一个 ajax 传输或直接使用 XmlHttpRequest。使用 xhr,您需要设置 xhr.responseType = "blob"
并从 xhr.response
读取 blob。
2/ 假设您的 js 代码片段是整个函数,您(尝试)获取二进制内容,解析 zip 文件,重新生成它,将内容提供给用户。可以直接给出结果:
// with xhr.responseType = "arraybuffer"
var arraybuffer = xhr.response;
var blob = new Blob([arraybuffer], {type:"application/zip"});
saveAs(blob, "example.zip");
// with xhr.responseType = "blob"
var blob = xhr.response;
saveAs(blob, "example.zip");
编辑:示例:
with jquery.binarytransport.js(任何允许您下载 Blob 或 ArrayBuffer 的库都可以)
$.ajax({
url: "../SharedAPI/documents/zip",
dataType: 'binary', // to use the binary transport
// responseType:'blob', this is the default
// [...]
success: function (blob) {
// the result is a blob, we can trigger the download directly
saveAs(blob, "example.zip");
}
// [...]
});
使用原始 XMLHttpRequest,你可以看到这个 question,你只需要添加一个 xhr.responseType = "blob"
就可以得到一个 blob。
我从未使用过 C#,但据我所知,[FromBody]
对数据格式非常敏感,第一个解决方案在您的情况下应该更容易实施。
在我的 MVC 项目中,我有一个 AJAX 对 Web API 的调用。
我发送了一系列文档的路由,API(应该)压缩它们,returns 压缩文件。
self.zipDocs = function (docs, callback) {
$.ajax({
url: "../SharedAPI/documents/zip",
type: "POST",
data: docs,
contentType: "application/json",
success: function (data) {
var zip = new JSZip(data);
var content = zip.generate({ type: "blob" });
saveAs(content, "example.zip");
},
error: function (data) {
callback(data);
}
});
}
以及我在 Web 上的 ZipDocs 功能API(使用 DotNetZip 库):
[HttpPost]
[Route("documents/zip")]
public HttpResponseMessage ZipDocs([FromBody] string[] docs)
{
using (var zipFile = new ZipFile())
{
zipFile.AddFiles(docs, false, "");
return ZipContentResult(zipFile);
}
}
protected HttpResponseMessage ZipContentResult(ZipFile zipFile)
{
// inspired from
var pushStreamContent = new PushStreamContent((stream, content, context) =>
{
zipFile.Save(stream);
stream.Close(); // After save we close the stream to signal that we are done writing.
}, "application/zip");
return new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent };
}
但是当返回 Zip 时,我收到以下错误:
Uncaught Error: Corrupted zip: missing 16053 bytes.
真正奇怪的是,当我将压缩文件 API 保存到磁盘时 它被正确保存 我可以毫无问题地打开文件!
我做错了什么?我错过了什么吗? 请帮忙!
提前致谢。
两件事:
1/ $.ajax
处理文本响应并将尝试 (utf-8) 解码内容:您的 zip 文件不是文本,您将得到损坏的内容。 jQuery doesn't support binary content 所以你需要使用之前的 link 并在 jQuery 上添加一个 ajax 传输或直接使用 XmlHttpRequest。使用 xhr,您需要设置 xhr.responseType = "blob"
并从 xhr.response
读取 blob。
2/ 假设您的 js 代码片段是整个函数,您(尝试)获取二进制内容,解析 zip 文件,重新生成它,将内容提供给用户。可以直接给出结果:
// with xhr.responseType = "arraybuffer"
var arraybuffer = xhr.response;
var blob = new Blob([arraybuffer], {type:"application/zip"});
saveAs(blob, "example.zip");
// with xhr.responseType = "blob"
var blob = xhr.response;
saveAs(blob, "example.zip");
编辑:示例:
with jquery.binarytransport.js(任何允许您下载 Blob 或 ArrayBuffer 的库都可以)
$.ajax({
url: "../SharedAPI/documents/zip",
dataType: 'binary', // to use the binary transport
// responseType:'blob', this is the default
// [...]
success: function (blob) {
// the result is a blob, we can trigger the download directly
saveAs(blob, "example.zip");
}
// [...]
});
使用原始 XMLHttpRequest,你可以看到这个 question,你只需要添加一个 xhr.responseType = "blob"
就可以得到一个 blob。
我从未使用过 C#,但据我所知,[FromBody]
对数据格式非常敏感,第一个解决方案在您的情况下应该更容易实施。