我正在使用AngularJS和WCF实现文件下载。我的后端是一个在IIS中托管的.NET项目。该文件被序列化为一个字节数组,然后在客户端我利用File API来保存内容。
为了简化问题,后端就像:
[WebInvoke(Method = "GET", UriTemplate = "FileService?path={path}")]
[OperationContract]
public byte[] DownloadFileBaseOnPath(string path)
{
using (var memoryStream = new MemoryStream())
{
var fileStream = File.OpenRead(path);
fileStream.CopyTo(memoryStream);
fileStream.Close();
WebOperationContext.Current.OutgoingResponse.Headers["Content-Disposition"] = "attachment; filename=\"Whatever\"";
WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream"; // treat all files as binary file
return memoryStream.ToArray();
}
}
在客户端,它只发送一个GET请求来获取这些字节,转换为blob并保存。
function sendGetReq(url, config) {
return $http.get(url, config).then(function(response) {
return response.data;
});
}
然后保存文件:
function SaveFile(url) {
var downloadRequest = sendGetReq(url);
downloadRequest.then(function(data){
var aLink = document.createElement('a');
var byteArray = new Uint8Array(data);
var blob = new Blob([byteArray], { type: 'application/octet-stream'});
var downloadUrl = URL.createObjectURL(blob);
aLink.setAttribute('href', downloadUrl);
aLink.setAttribute('download', fileNameDoesNotMatter);
if (document.createEvent) {
var event = document.createEvent('MouseEvents');
event.initEvent('click', false, false);
aLink.dispatchEvent(event);
}
else {
aLink.click();
}
setTimeout(function () {
URL.revokeObjectURL(downloadUrl);
}, 1000); // cleanup
});
}
这种方法适用于小文件。我可以成功下载高达64MB的文件。但是当我尝试下载大于64MB的文件时,Chrome中的response.body是空的。我还用Fiddler来捕获流量。根据Fiddler的说法,Back-end已成功序列化字节数组并将其返回。请参阅下面的截图。
在这个例子中,我试图下载一个70MB的文件:
知道为什么对于70MB以上的文件来说这是空的?虽然响应本身超过200MB,但我确实有足够的内存。
关于WCF后端,我知道在涉及大文件时我应该使用Stream Mode。但我的应用程序的典型用途是下载小于10MB的文件。所以我希望先把它弄清楚。
谢谢
答案 0 :(得分:0)
回答我自己的问题。
老实说,我不知道出了什么问题。如果我将其作为字节数组传输,问题仍然存在。我最终通过返回流而放弃了这种方法。然后在客户端,添加以下配置
{responseType : blob}
并将其另存为blob。