[英]Corrupted Zip while returning from Web API?
On my MVC project I have an AJAX call to a Web API. 在我的MVC项目中,我有一个对Web API的AJAX调用。
I send an array of documents' routes, the API (should) zips them and returns the zip file . 我发送了一系列文档的路由, API(应该)将它们压缩并返回zip文件 。
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);
}
});
}
And my ZipDocs function on the WebAPI (using the DotNetZip library): 还有我在WebAPI上的ZipDocs函数(使用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 http://stackoverflow.com/a/16171977/92756
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 };
}
But when the Zip is returned I got the following error: 但是,当Zip返回时,出现以下错误:
Uncaught Error: Corrupted zip: missing 16053 bytes.
未捕获的错误:损坏的zip:缺少16053个字节。
What is really weird, when I save on the API the zip file to the disk it gets saved properly and I can open the file without any problem! 真正奇怪的是,当我将zip文件保存到磁盘上时, 它会正确保存,并且可以毫无问题地打开该文件!
What am I doing wrong? 我究竟做错了什么? am I missing something?
我错过了什么吗? Please help!
请帮忙!
Thanks in advance. 提前致谢。
Two things: 两件事情:
1/ $.ajax
handles text responses and will try to (utf-8) decode the content: your zip file isn't text, you will get a corrupted content. 1 /
$.ajax
处理文本响应,并尝试(utf-8)解码内容:您的zip文件不是文本,您将获得损坏的内容。 jQuery doesn't support binary content so you need to use the previous link and add an ajax transport on jQuery or use directly a XmlHttpRequest. jQuery 不支持二进制内容,因此您需要使用上一个链接并在jQuery上添加ajax传输或直接使用XmlHttpRequest。 With an xhr, you need to set
xhr.responseType = "blob"
and read from xhr.response
the blob. 对于xhr,您需要设置
xhr.responseType = "blob"
并从xhr.response
读取该blob。
2/ assuming your js code snippet is the whole function, you (try to) get a binary content, parse the zip file, re-generate it, give the content to the user. 2 /假设您的js代码段是整个函数,则您(尝试)获取二进制内容,解析zip文件,重新生成,然后将内容提供给用户。 You can give directly the result:
您可以直接给出结果:
// 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");
Edit: examples: 编辑:例子:
with jquery.binarytransport.js (any library that let you download a Blob or an ArrayBuffer will do) 与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");
}
// [...]
});
with a raw XMLHttpRequest, you can see this question , you just need to add a xhr.responseType = "blob"
to get a blob. 使用原始XMLHttpRequest,您可以看到此问题 ,只需添加一个
xhr.responseType = "blob"
即可获得一个blob。
I never used C# but from what I can see, [FromBody]
is quite sensitive to the format of the data, the first solution should be easier to implement in your case. 我从未使用过C#,但从我的了解中可以看出,
[FromBody]
对数据格式非常敏感,第一种解决方案在您的情况下应该更容易实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.